Skip to content

Commit 9867094

Browse files
authored
Merge pull request #10 from Absulit/add_button
Add button and other optimizations
2 parents dd4f508 + 08007ca commit 9867094

2 files changed

Lines changed: 93 additions & 33 deletions

File tree

build/gamepad.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/gamepad.js

Lines changed: 92 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,18 @@ export class Button extends EventTarget {
2626
#name = null;
2727
#index = null;
2828
#debug = false;
29+
#angle = 0;
30+
#distance = 0;
31+
#proportion = 0;
32+
#touched = false;
33+
#value = 0;
34+
#lastValue = 0;
2935

36+
/**
37+
*
38+
* @param {string} name
39+
* @param {Number} index
40+
*/
3041
constructor(name, index) {
3142
super()
3243
this.#name = name;
@@ -48,18 +59,75 @@ export class Button extends EventTarget {
4859
this.#debug = v;
4960
}
5061

62+
/**
63+
* angle in radians
64+
* This is done by GamepadJS, you don't have to set it.
65+
*/
66+
get angle() {
67+
return this.#angle;
68+
}
69+
70+
71+
/**
72+
* distance from the center of the joystick
73+
*/
74+
get distance() {
75+
return this.#distance;
76+
}
77+
78+
get proportion() {
79+
return this.#proportion;
80+
}
81+
82+
get touched() {
83+
return this.#touched;
84+
}
85+
86+
get value() {
87+
return this.#value
88+
}
89+
90+
/**
91+
* only used for Firefox fix
92+
*/
93+
set value(v) {
94+
this.#lastValue = this.#value;
95+
this.#value = v;
96+
this.#touched = -.9 < v;
97+
// to solve a bug if the value starts in zero (Firefox)
98+
if (this.#lastValue === this.#value && this.#value === 0) {
99+
this.#touched = false;
100+
}
101+
if (this.#touched) {
102+
this.#value = (this.#value + 1) * .5;
103+
}
104+
this.#dispatchEventIfPushed();
105+
}
106+
51107
/**
52108
* To copy properties from the Gamepad API button
53109
* @param {Object} v
54110
*/
55-
setProperties(v) {
56-
for (let p in v) {
57-
this[p] = v[p]
111+
setProperties({ pressed, touched, value, x, y }) {
112+
this.pressed = pressed
113+
this.#touched = touched
114+
this.x = x;
115+
this.y = y;
116+
this.#value = value;
117+
if (this.x && this.y) {
118+
const { x, y } = this; // TODO replace with #x and #y
119+
this.#distance = Math.sqrt(x * x + y * y);
120+
this.#angle = Math.atan2(-y, x);
121+
this.#proportion = this.#angle / TAU;
122+
if (this.#angle < 0) this.#angle += TAU;
123+
124+
this.#touched = (Math.abs(x) > .1) || (Math.abs(y) > .1);
58125
}
126+
this.#dispatchEventIfPushed();
59127
}
60128

61-
dispatchEventIfPushed() {
62-
if (this.touched && !this.#pushed) {
129+
#dispatchEventIfPushed() {
130+
if (this.#touched && !this.#pushed) {
63131
this.dispatchEvent(new Event(Button.PUSHED));
64132
this.#pushed = true;
65133
this.#released = false;
@@ -72,7 +140,7 @@ export class Button extends EventTarget {
72140
console.log(`Button PUSHED: Name: ${this.#name}, Index: ${index}`);
73141
}
74142
}
75-
if (!this.touched && !this.#released) {
143+
if (!this.#touched && !this.#released) {
76144
this.dispatchEvent(new Event(Button.RELEASED));
77145
this.#pushed = false;
78146
this.#released = true;
@@ -148,6 +216,15 @@ export class Control extends EventTarget {
148216
});
149217
}
150218

219+
/**
220+
* Add an button with alias `name`
221+
* @param {string} name Name the button will be called on later
222+
* @param {Number} index button index from the Gamepad API
223+
*/
224+
addButton(name, index) {
225+
this.#buttons[name] = new Button(name, index);
226+
}
227+
151228
get hasVibrationActuator() {
152229
return !!this.#gamepad.vibrationActuator;
153230
}
@@ -207,11 +284,10 @@ export class GamepadJS extends EventTarget {
207284
console.log(gamepad.mapping);
208285

209286
for (let buttonName in this.#mapping.buttons) {
210-
// TODO controls.addButton method
211-
control.buttons[buttonName] = new Button(buttonName, this.#mapping.buttons[buttonName]);
287+
control.addButton(buttonName, this.#mapping.buttons[buttonName]);
212288
}
213289
for (let buttonName in this.#mapping.axes) {
214-
control.buttons[buttonName] = new Button(buttonName, this.#mapping.axes[buttonName]);
290+
control.addButton(buttonName, this.#mapping.axes[buttonName]);
215291
}
216292

217293
this.dispatchEvent(new CustomEvent(GamepadJS.CONNECTED, { detail: control }));
@@ -245,7 +321,7 @@ export class GamepadJS extends EventTarget {
245321

246322
#isObject = v => typeof v === 'object' && v !== null;
247323

248-
#distance = (x, y) => Math.sqrt(x * x + y * y);
324+
// #distance = (x, y) => Math.sqrt(x * x + y * y);
249325

250326
/**
251327
* To be called in the `requestAnimationFrame`
@@ -262,7 +338,7 @@ export class GamepadJS extends EventTarget {
262338
continue;
263339
}
264340

265-
if(!control.hasVibrationActuator){
341+
if (!control.hasVibrationActuator) {
266342
control.gamepad = gamepad;
267343
}
268344

@@ -272,38 +348,22 @@ export class GamepadJS extends EventTarget {
272348
const button = control.buttons[buttonName];
273349
const gamepadButton = gamepad.buttons[button.index];
274350
button.debug = this.#debug;
275-
button.setProperties(gamepadButton)
276-
button.dispatchEventIfPushed();
351+
button.setProperties(gamepadButton);
277352
}
278353

279354
for (let buttonName in mapping.axes) {
280355
const mappingButton = mapping.axes[buttonName];
281356
const isObject = this.#isObject(mappingButton);
282357

283-
let button = control.buttons[buttonName];
358+
const button = control.buttons[buttonName];
359+
button.debug = this.#debug;
284360

285361
if (isObject) {
286-
button = control.buttons[buttonName];
287-
button.debug = this.#debug;
288362
button.setProperties({ x: gamepad.axes[mappingButton.x], y: gamepad.axes[mappingButton.y] })
289-
button.touched = (Math.abs(button.x) > .1) || (Math.abs(button.y) > .1);
290-
button.angle = Math.atan2(-button.y, button.x);
291-
button.proportion = button.angle / TAU; // TODO move to Button class
292-
if (button.angle < 0) button.angle += TAU;
293-
button.distance = this.#distance(button.x, button.y);
294363
} else {
295-
const value = gamepad.axes[mappingButton];
296-
button = control.buttons[buttonName];
297-
button.debug = this.#debug;
298-
button.lastValue = button.value;
299-
button.value = value;
300-
button.touched = -.9 < value;
301-
// to solve a bug if the value starts in zero
302-
if (button.lastValue == button.value && button.value == 0) {
303-
button.touched = false;
304-
}
364+
// Firefox fix
365+
button.value = gamepad.axes[mappingButton]
305366
}
306-
button.dispatchEventIfPushed();
307367
}
308368
}
309369

0 commit comments

Comments
 (0)