-
-
Save jakearchibald/e4a2a63a5b9adf2580d0667c70dcaf82 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export declare function gamepadButtonPress(listeners: { | |
[button: number]: () => void; | |
}): Promise<void>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export async function gamepadButtonPress(listeners) { | |
const lastStates = []; | |
while (true) { | |
const gamepads = [...navigator.getGamepads()].filter(Boolean); | |
if (gamepads.length === 0) { | |
await new Promise((resolve) => { | |
addEventListener('gamepadconnected', () => resolve(), { once: true }); | |
}); | |
continue; | |
} | |
await new Promise((r) => requestAnimationFrame(r)); | |
for (const gamepad of gamepads) { | |
const state = gamepad.buttons.map((button) => button.pressed); | |
const lastState = lastStates[gamepad.index] || state.map(() => false); | |
for (const [buttonIndex, callback] of Object.entries(listeners)) { | |
const wasPressed = lastState[buttonIndex]; | |
const pressed = state[buttonIndex]; | |
if (pressed && !wasPressed) callback(); | |
} | |
lastStates[gamepad.index] = state; | |
} | |
} | |
} | |
// Example usage: | |
gamepadButtonPress({ | |
0: () => presentation.next(), | |
3: () => presentation.previous(), | |
}); |
@Teiem good point! I guess I was thinking too much about making a generic "buttondown", and forgot that I have access to the listeners.
I updated the code. I guess you could optimise the state storage in a similar way.
in the example usage you cna also pass the function by reference (though i can understand writing it this way for clarification you are passing functions ^^)
@jonnytest1 that depends on how the function is written, and whether it depends on a particular this
value. https://web.dev/javascript-this/
If there was a way to detect button release as well, it would cover 90% of gamedev needs that use d-pad for movement :)
@luminarious instead of:
if (pressed && !wasPressed) callback();
It would be:
if (wasPressed && !pressed) callback();
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I would iterate over the
listeners
since they should be less than the number of buttons.