UNPKG

contro-max

Version:

Game controls done in the best possible way!

94 lines (93 loc) 4.1 kB
import { findButtonNumber } from './gamepad'; import { TypedEventEmitter } from './typedEventEmitter'; export const gamepadSticks = { left: { label: 'Left stick', xAxis: 0, yAxis: 1 }, right: { label: 'Right stick', xAxis: 2, yAxis: 3 }, }; export class GamepadsStore extends TypedEventEmitter { // static getConnectedGamepadIndexes() { // return new Set((navigator.getGamepads().filter(Boolean) as Gamepad[]).map(gamepad => gamepad.index)) // } static getConnectedGamepads() { return [...navigator.getGamepads()].filter(Boolean); } static queryButton(whichGamepad, button) { const buttonNumber = findButtonNumber(button); if (whichGamepad === 'all') return navigator.getGamepads().some(gamepad => gamepad?.buttons[buttonNumber].pressed); return !!navigator.getGamepads()[whichGamepad]?.buttons[buttonNumber].pressed; } static queryStick(stick, gamepad) { // const gamepadConnectedIndex = // which === 'first' // ? 0 // : which === 'last' // ? this.connectedGamepads.length - 1 // : this.connectedGamepads.findIndex(({ index }) => index === which) // const gamepad = this.connectedGamepads[gamepadConnectedIndex] if (gamepad === undefined) throw new Error('Queried disconnected gamepad'); const resolvedStick = typeof stick === 'string' ? gamepadSticks[stick] : stick; // if (!this.isConnected()) return? return { x: gamepad.axes[resolvedStick.xAxis], z: gamepad.axes[resolvedStick.yAxis], }; } connectedGamepads = GamepadsStore.getConnectedGamepads(); constructor() { super(); // public enabledGamepad: WhichGamepad = 'all', // public gamepadButtonsMap window.addEventListener('gamepadconnected', this.gamepadEvent); window.addEventListener('gamepaddisconnected', this.gamepadEvent); } dispose() { window.removeEventListener('gamepadconnected', this.gamepadEvent); window.removeEventListener('gamepaddisconnected', this.gamepadEvent); } gamepadEvent = ({ gamepad, type, ...rest }) => { const connectedGamepadsLength = this.connectedGamepads.length; if (type === 'gamepadconnected') { if (gamepad.mapping !== 'standard') { console.warn(`Unknown gamepad mapping ${gamepad.mapping}. Ignoring..`); return; } this.connectedGamepads.push(gamepad); } else { const gamepadIndex = this.connectedGamepads.indexOf(gamepad); // Is this even possible? // if (gamepadIndex === -1) this.connectedGamepads = GamepadsStore.getConnectedGamepads() this.connectedGamepads.splice(gamepadIndex, 1); } if (connectedGamepadsLength === 0 && this.connectedGamepads.length > 0) void this.emit('firstConnected', this.connectedGamepads.values().next().value); if (connectedGamepadsLength > 0 && this.connectedGamepads.length === 0) void this.emit('lastDisconnected'); }; } // export const createGamepadsStore = () => { // const , // disabledGamepadIndexes: number[] = []; // return { // connectedGamepads, // /** // * @returns `false` if was already enabled // */ // disableGamepad: (gamepadIndex: number) => !disabledGamepadIndexes.includes(gamepadIndex) && (disabledGamepadIndexes.push(gamepadIndex), true), // /** // * @returns `false` if was already enabled // */ // enableGamepad: (gamepadIndex: number) => disabledGamepadIndexes.includes(gamepadIndex) && // (disabledGamepadIndexes.splice(disabledGamepadIndexes.indexOf(gamepadIndex), 1), true), // /** // * @returns whether button is pressed // */ // queryButton: (button: string): boolean => { // }, // queryButton: (button: string | number) => { // const buttonNumber = findButtonNumber(button); // return buttonNumber; // } // }; // };