Browse code

use gamepad ids to store layout

devnewton authored on 13/03/2018 13:08:30
Showing 5 changed files
... ...
@@ -28,7 +28,7 @@ export class UnderthiefGame extends Phaser.Game {
28 28
         this.state.add('Help2', Help2);
29 29
         this.state.add('Options', Options);
30 30
         this.state.add('GamepadOptionsLayout', GamepadOptionsLayout);
31
-        this.state.add('GamepadOptionsBindAxis', GamepadOptionsBindAxisOrButton);
31
+        this.state.add('GamepadOptionsBindAxisOrButton', GamepadOptionsBindAxisOrButton);
32 32
         this.state.add('KeyboardOptions', KeyboardOptions);
33 33
         this.state.add('KeyboardOptionsBindKey', KeyboardOptionsBindKey);
34 34
         this.state.add('GamepadOptions', GamepadOptions);
... ...
@@ -7,7 +7,7 @@ import { GamepadUtils } from "../utils/GamepadUtils";
7 7
 
8 8
 export class GamepadOptionsBindAxisOrButton extends AbstractState {
9 9
 
10
-    bindings = [
10
+    bindingsDescription = [
11 11
         { label: 'Pull move X axis', localStorageKeySuffix: 'moveXAxis' },
12 12
         { label: 'Pull move Y axis', localStorageKeySuffix: 'moveYAxis' },
13 13
         { label: 'Press hammer button', localStorageKeySuffix: 'hammerButton' },
... ...
@@ -20,6 +20,7 @@ export class GamepadOptionsBindAxisOrButton extends AbstractState {
20 20
     padIndex = 1;
21 21
     axisButtons: Phaser.Group;
22 22
     buttonsButtons: Phaser.Group;
23
+    bindings = {};
23 24
 
24 25
     constructor() {
25 26
         super();
... ...
@@ -30,12 +31,12 @@ export class GamepadOptionsBindAxisOrButton extends AbstractState {
30 31
         MenuMiniButton.preload(this.game);
31 32
     }
32 33
 
33
-    init(padIndex: number, binding: number = 0) {
34
-        this.padIndex = padIndex || 1;
35
-        this.pad = this.input.gamepad['pad' + this.padIndex];
36
-        if (binding >= this.bindings.length) {
34
+    init(padIndex: number, binding: number = 0, bindings: any) {
35
+        this.bindings = bindings || {};
36
+        this.pad = GamepadUtils.gamepadByIndex(this.game, padIndex);
37
+        if (binding >= this.bindingsDescription.length) {
37 38
             this.currentBinding = 0;
38
-            (this.game as UnderthiefGame).controllers.getPad(this.padIndex).useCustomGamepadLayout(padIndex);
39
+            localStorage.setItem('gamepad.' + GamepadUtils.gamepadId(this.pad) + '.layout', JSON.stringify(this.bindings));
39 40
             this.game.state.start('GamepadOptions');
40 41
         } else {
41 42
             this.currentBinding = binding;
... ...
@@ -44,7 +45,7 @@ export class GamepadOptionsBindAxisOrButton extends AbstractState {
44 45
 
45 46
     create() {
46 47
         super.create();
47
-        let logo = this.game.add.text(this.game.world.centerX, 0, this.bindings[this.currentBinding].label, { font: "42px monospace", fill: 'white' });
48
+        let logo = this.game.add.text(this.game.world.centerX, 0, this.bindingsDescription[this.currentBinding].label, { font: "42px monospace", fill: 'white' });
48 49
         logo.scale.x = 2;
49 50
         logo.scale.y = 2;
50 51
         logo.anchor.setTo(0.5, 0);
... ...
@@ -83,7 +84,7 @@ export class GamepadOptionsBindAxisOrButton extends AbstractState {
83 84
 
84 85
     update() {
85 86
         super.update();
86
-        if (this.bindings[this.currentBinding].localStorageKeySuffix.match(/axis/gi)) {
87
+        if (this.bindingsDescription[this.currentBinding].localStorageKeySuffix.match(/axis/gi)) {
87 88
             this.axisButtons.visible = true;
88 89
             this.buttonsButtons.visible = false;
89 90
         } else {
... ...
@@ -93,13 +94,13 @@ export class GamepadOptionsBindAxisOrButton extends AbstractState {
93 94
     }
94 95
 
95 96
     bindAxis(axisCode: number) {
96
-        localStorage.setItem('gamepad' + this.padIndex + '.layout.custom.' + this.bindings[this.currentBinding].localStorageKeySuffix, '' + axisCode);
97
-        this.game.state.start('GamepadOptionsBindAxis', true, false, this.padIndex, this.currentBinding + 1);
97
+        this.bindings[this.bindingsDescription[this.currentBinding].localStorageKeySuffix] = axisCode;
98
+        this.game.state.start('GamepadOptionsBindAxisOrButton', true, false, this.padIndex, this.currentBinding + 1);
98 99
     }
99 100
 
100 101
     bindButton(buttonCode: number) {
101
-        localStorage.setItem('gamepad' + this.padIndex + '.layout.custom.' + this.bindings[this.currentBinding].localStorageKeySuffix, '' + buttonCode);
102
-        this.game.state.start('GamepadOptionsBindAxis', true, false, this.padIndex, this.currentBinding + 1);
102
+        this.bindings[this.bindingsDescription[this.currentBinding].localStorageKeySuffix] = buttonCode;
103
+        this.game.state.start('GamepadOptionsBindAxisOrButton', true, false, this.padIndex, this.currentBinding + 1);
103 104
     }
104 105
 }
105 106
 
... ...
@@ -2,6 +2,7 @@
2 2
 import {AbstractState} from "./AbstractState";
3 3
 import {Menu} from "../ui/Menu";
4 4
 import {UnderthiefGame} from "../UnderthiefGame";
5
+import {GamepadUtils} from '../utils/GamepadUtils';
5 6
 
6 7
 export class GamepadOptionsLayout extends AbstractState {
7 8
     padIndex: number;
... ...
@@ -27,11 +28,11 @@ export class GamepadOptionsLayout extends AbstractState {
27 28
 
28 29
         const menu = new Menu(this.game).disableGamepadCursor();
29 30
         menu.button("Xbox", 200, 200, () => {
30
-            (this.game as UnderthiefGame).controllers.getPad(this.padIndex).useXboxLayout(this.padIndex);
31
+            localStorage.setItem('gamepad.' + GamepadUtils.gamepadId(GamepadUtils.gamepadByIndex(this.game, this.padIndex)) + '.layout', 'xbox');
31 32
             this.game.state.start('Options');
32 33
         });
33 34
         menu.button("Custom", 200, 300, () => {
34
-            this.game.state.start('GamepadOptionsBindAxis', true, false, this.padIndex);
35
+            this.game.state.start('GamepadOptionsBindAxisOrButton', true, false, this.padIndex);
35 36
         });
36 37
         menu.button("Back", 200, 500, () => this.game.state.start('Options'));
37 38
     }
... ...
@@ -1,5 +1,7 @@
1 1
 /// <reference path="../../typings/phaser.d.ts"/>
2 2
 
3
+import { GamepadUtils } from "./GamepadUtils";
4
+
3 5
 export enum ControllerType {
4 6
     CPU = -1,
5 7
     KEYBOARD = 0,
... ...
@@ -229,60 +231,59 @@ export class KeyboardControls extends AbstractControls {
229 231
 
230 232
 }
231 233
 
234
+export interface PadControlsMapping {
235
+    moveXAxis?: number;
236
+    moveYAxis?: number;
237
+    dashButton?: number;
238
+    menuButton?: number;
239
+    hammerTimeButton?: number;
240
+}
241
+
232 242
 export class PadControls extends AbstractControls {
233
-    pad: Phaser.SinglePad;
234
-    game: Phaser.Game;
235
-    moveXAxis: number;
236
-    moveYAxis: number;
237
-    dashButton: number;
238
-    menuButton: number;
239
-    hammerTimeButton: number;
243
+    padIndex: number;
244
+    private pad: Phaser.SinglePad;
245
+    private game: Phaser.Game;
246
+    private moveXAxis: number;
247
+    private moveYAxis: number;
248
+    private dashButton: number;
249
+    private menuButton: number;
250
+    private hammerTimeButton: number;
240 251
 
241 252
     constructor(game: Phaser.Game, padIndex: number) {
242 253
         super();
243 254
         this.game = game;
244 255
         game.input.gamepad.start();
245
-        this.setupGamepadLayout(padIndex);
246
-    }
247
-
248
-    private setupGamepadLayout(padIndex: number) {
249
-        let layout = localStorage.getItem('gamepad' + padIndex + '.layout');
250
-        if (null == layout || layout == 'xbox') {
251
-            this.useXboxLayout(padIndex);
252
-        } else if (layout == 'custom') {
253
-            this.useCustomGamepadLayout(padIndex);
256
+        this.padIndex = padIndex;
257
+    }
258
+
259
+    private checkPad(): boolean {
260
+        let pad = GamepadUtils.gamepadByIndex(this.game, this.padIndex);
261
+        if (pad != null && this.pad != pad) {
262
+            this.pad = pad;
263
+            let layout: PadControlsMapping = {};
264
+            try {
265
+                layout = JSON.parse(localStorage.getItem('gamepad.' + GamepadUtils.gamepadId(this.pad) + '.layout')) || {};
266
+            } catch (e) {
267
+                layout = {};
268
+            }
269
+            this.moveXAxis = layout.moveXAxis || Phaser.Gamepad.XBOX360_STICK_LEFT_X;
270
+            this.moveYAxis = layout.moveYAxis || Phaser.Gamepad.XBOX360_STICK_LEFT_Y;
271
+            this.dashButton = layout.dashButton || Phaser.Gamepad.XBOX360_X;
272
+            this.menuButton = layout.menuButton || Phaser.Gamepad.XBOX360_START;
273
+            this.hammerTimeButton = layout.hammerTimeButton || Phaser.Gamepad.XBOX360_A;
274
+            return true;
275
+        } else {
276
+            return false;
254 277
         }
255 278
     }
256 279
 
257
-    useXboxLayout(padIndex: number) {
258
-        padIndex = padIndex || 1;
259
-        this.pad = this.game.input.gamepad['pad' + padIndex];
260
-        this.moveXAxis = Phaser.Gamepad.XBOX360_STICK_LEFT_X;
261
-        this.moveYAxis = Phaser.Gamepad.XBOX360_STICK_LEFT_Y;
262
-        this.dashButton = Phaser.Gamepad.XBOX360_X;
263
-        this.menuButton = Phaser.Gamepad.XBOX360_START;
264
-        this.hammerTimeButton = Phaser.Gamepad.XBOX360_A;
265
-        localStorage.setItem('gamepad' + padIndex + '.layout', 'xbox');
266
-    }
267
-
268
-    useCustomGamepadLayout(padIndex: number) {
269
-        padIndex = padIndex || 1;
270
-        this.pad = this.game.input.gamepad['pad' + padIndex];
271
-        this.moveXAxis = this.readNumberFromLocalStorage('gamepad' + padIndex + '.layout.custom.moveXAxis', Phaser.Gamepad.XBOX360_STICK_LEFT_X);
272
-        this.moveYAxis = this.readNumberFromLocalStorage('gamepad' + padIndex + '.layout.custom.moveYAxis', Phaser.Gamepad.XBOX360_STICK_LEFT_Y);
273
-        this.dashButton = this.readNumberFromLocalStorage('gamepad' + padIndex + '.layout.custom.dashButton', Phaser.Gamepad.XBOX360_X);
274
-        this.menuButton = this.readNumberFromLocalStorage('gamepad' + padIndex + '.layout.custom.menuButton', Phaser.Gamepad.XBOX360_START);
275
-        this.hammerTimeButton = this.readNumberFromLocalStorage('gamepad' + padIndex + '.layout.custom.hammerButton', Phaser.Gamepad.XBOX360_A);
276
-        localStorage.setItem('gamepad' + padIndex + '.layout', 'custom');
277
-    }
278
-
279 280
     dashingAngle(playerPos: Phaser.Point): number {
280
-        if (this.pad && this.pad.isDown(this.dashButton)) {
281
+        if (this.checkPad() && this.pad.isDown(this.dashButton)) {
281 282
             return this.lookingAngle();
282 283
         }
283 284
     }
284 285
 
285
-    lookingAngle(): number {
286
+    private lookingAngle(): number {
286 287
         let dx = this.pad.axis(this.moveXAxis);
287 288
         let dy = this.pad.axis(this.moveYAxis);
288 289
         dx = Math.abs(dx) <= this.pad.deadZone ? 0 : dx;
... ...
@@ -293,29 +294,29 @@ export class PadControls extends AbstractControls {
293 294
             return null;
294 295
         }
295 296
     }
297
+
296 298
     isGoingUp(): boolean {
297
-        return this.pad && this.pad.axis(this.moveYAxis) < -this.pad.deadZone
299
+        return this.checkPad() && this.pad.axis(this.moveYAxis) < -this.pad.deadZone
298 300
             ;
299 301
     }
300 302
     isGoingDown(): boolean {
301
-        return this.pad && this.pad.axis(this.moveYAxis) > this.pad.deadZone
302
-            ;
303
+        return this.checkPad() && this.pad.axis(this.moveYAxis) > this.pad.deadZone;
303 304
     }
304 305
 
305 306
     isGoingLeft(): boolean {
306
-        return this.pad && this.pad.axis(this.moveXAxis) < -this.pad.deadZone;
307
+        return this.checkPad() && this.pad.axis(this.moveXAxis) < -this.pad.deadZone;
307 308
     }
308 309
 
309 310
     isGoingRight(): boolean {
310
-        return this.pad && this.pad.axis(this.moveXAxis) > this.pad.deadZone;
311
+        return this.checkPad() && this.pad.axis(this.moveXAxis) > this.pad.deadZone;
311 312
     }
312 313
 
313 314
     isHammerTime(): boolean {
314
-        return this.pad && this.pad.isDown(this.hammerTimeButton);
315
+        return this.checkPad() && this.pad.isDown(this.hammerTimeButton);
315 316
     }
316 317
 
317 318
     isMenuAsked(): boolean {
318
-        return this.pad && this.pad.isDown(this.menuButton);
319
+        return this.checkPad() && this.pad.isDown(this.menuButton);
319 320
     }
320 321
 
321 322
 }
322 323
\ No newline at end of file
... ...
@@ -15,4 +15,16 @@ export class GamepadUtils {
15 15
             return 0xFF0000;
16 16
         }
17 17
     }
18
+    static gamepadId(pad: Phaser.SinglePad): string {
19
+        let anyPad = <any>pad;
20
+        if (anyPad._rawPad) {
21
+            return anyPad._rawPad.id;
22
+        } else {
23
+            return null;
24
+        }
25
+    }
26
+
27
+    static gamepadByIndex(game: Phaser.Game, padIndex : number): Phaser.SinglePad {
28
+        return game.input.gamepad['pad' + padIndex];
29
+    }
18 30
 }
19 31
\ No newline at end of file