class GamepadHandler { gamepads; timeout; listeners; constructor() { this.buttonLabels = { 0: 'BUTTON_1', 1: 'BUTTON_2', 2: 'BUTTON_3', 3: 'BUTTON_4', 4: 'LEFT_SHOULDER', 5: 'RIGHT_SHOULDER', 6: 'LEFT_SHOULDER_BOTTOM', 7: 'RIGHT_SHOULDER_BOTTOM', 8: 'SELECT', 9: 'START', 10: 'LEFT_STICK', 11: 'RIGHT_STICK', 12: 'DPAD_UP', 13: 'DPAD_DOWN', 14: 'DPAD_LEFT', 15: 'DPAD_RIGHT', }; this.gamepads = []; this.listeners = {}; this.timeout = null; this.loop(); } terminate() { window.clearTimeout(this.timeout); } getGamepads() { return navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []); } loop() { this.updateGamepadState(); this.timeout = setTimeout(this.loop.bind(this), 10); } updateGamepadState() { let gamepads = this.getGamepads(); if (!gamepads) return; if (!Array.isArray(gamepads) && gamepads.length) { let gp = []; for (let i=0; i { if (!gamepad) return; let hasGamepad = false; this.gamepads.forEach((oldGamepad, oldIndex) => { if (oldGamepad.index !== gamepad.index) return; const gamepadToSave = { axes: [], buttons: {}, index: oldGamepad.index, id: oldGamepad.id } hasGamepad = true; oldGamepad.axes.forEach((axis, axisIndex) => { const val = (axis < 0.01 && axis > -0.01) ? 0 : axis; const newVal = (gamepad.axes[axisIndex] < 0.01 && gamepad.axes[axisIndex] > -0.01) ? 0 : gamepad.axes[axisIndex]; if (newVal !== val) { const axis = ['LEFT_STICK_X', 'LEFT_STICK_Y', 'RIGHT_STICK_X', 'RIGHT_STICK_Y'][axisIndex]; if (!axis) return; this.dispatchEvent('axischanged', { axis: axis, value: newVal, index: gamepad.index, label: this.getAxisLabel(axis, newVal), gamepadIndex: gamepad.index, }); } gamepadToSave.axes[axisIndex] = newVal; }) gamepad.buttons.forEach((button, buttonIndex) => { let pressed = oldGamepad.buttons[buttonIndex] === 1.0; if (typeof oldGamepad.buttons[buttonIndex] === "object") { pressed = oldGamepad.buttons[buttonIndex].pressed; } let pressed2 = button === 1.0; if (typeof button === "object") { pressed2 = button.pressed; } gamepadToSave.buttons[buttonIndex] = {pressed:pressed2}; if (pressed !== pressed2) { if (pressed2) { this.dispatchEvent('buttondown', {index: buttonIndex, label: this.getButtonLabel(buttonIndex), gamepadIndex: gamepad.index}); } else { this.dispatchEvent('buttonup', {index: buttonIndex, label:this.getButtonLabel(buttonIndex), gamepadIndex: gamepad.index}); } } }) this.gamepads[oldIndex] = gamepadToSave; }) if (!hasGamepad) { this.gamepads.push(gamepads[index]); this.dispatchEvent('connected', {gamepadIndex: gamepad.index}); } }); for (let j=0; j 0.5 || value < -0.5) { if (value > 0) { valueLabel = '+1'; } else { valueLabel = '-1'; } } if (!axis || !valueLabel) { return null; } return `${axis}:${valueLabel}`; } } window.GamepadHandler = GamepadHandler;