diff --git a/src/js/core/input_distributor.js b/src/js/core/input_distributor.js index 59d64932..9f2f0a13 100644 --- a/src/js/core/input_distributor.js +++ b/src/js/core/input_distributor.js @@ -220,6 +220,24 @@ export class InputDistributor { } } + getGamepadAxes() { + if (this.connectedGamepadIndex === null) { + return { + x: 0, + y: 0, + }; + } + + const gamepad = navigator.getGamepads()[this.connectedGamepadIndex]; + + // Threshold 0.25 as the joysticks never return to exact 0 + // power to 9 function to decrease the sensitivity, to be ~0.25 at 85% + return { + x: Math.abs(gamepad.axes[0]) < 0.25 ? 0 : gamepad.axes[0], + y: Math.abs(gamepad.axes[1]) < 0.25 ? 0 : gamepad.axes[1], + }; + } + /** * @param {Event} event */ diff --git a/src/js/game/camera.js b/src/js/game/camera.js index 107d1fb4..7c7557f8 100644 --- a/src/js/game/camera.js +++ b/src/js/game/camera.js @@ -778,6 +778,7 @@ export class Camera extends BasicSerializableObject { this.internalUpdateCentering(now, physicsStepSizeMs); this.internalUpdateShake(now, physicsStepSizeMs); this.internalUpdateKeyboardForce(now, physicsStepSizeMs); + this.internalUpdateGamepadForce(now, physicsStepSizeMs); } this.clampZoomLevel(); } @@ -1008,4 +1009,24 @@ export class Camera extends BasicSerializableObject { this.center.y += moveAmount * forceY * movementSpeed; } } + + /** + * Updates the gamepad axis forces + * @param {number} now + * @param {number} dt Delta time + */ + internalUpdateGamepadForce(now, dt) { + const inputMgr = this.root.app.inputMgr; + + if (inputMgr.connectedGamepadIndex !== null && !this.currentlyMoving && this.desiredCenter == null) { + const limitingDimension = Math.min(this.root.gameWidth, this.root.gameHeight); + + const moveAmount = ((limitingDimension / 2048) * dt) / this.zoomLevel; + + let { x, y } = inputMgr.getGamepadAxes(); + + this.center.x += moveAmount * x * 2; + this.center.y += moveAmount * y * 2; + } + } }