`requestAnimationFrame()` blocked by a gamepad

36 views Asked by At

I'm trying to use the Gamepad API. It's a little bit tricky as it seems its API isn't that developped ? I mean, there is no "gamepadbuttondown" event. :( I found some library as 'awesome-react-gamepads', but because of some acamdemic constraint, I can only use native functionality, so I'm doing odd jobs.
To go through the lack of events possibilties, I have a kind of loop checking if a button is pressed, each turn. To avoid an infinite while, I'm using requestAnimationFrame(gameLoop) Like this :

if ("getGamepads" in navigator) {
    console.log("Gamepad API is supported");
} else {
    console.log("Gamepad API is not supported");
}

window.addEventListener("gamepadconnected", (e) => {
    GamepadList = navigator.getGamepads()
    console.log(GamepadList);
    gamepad = GamepadList[0];
    console.log(gamepad);
    gameLoop();
});

window.addEventListener("gamepaddisconnected", (e) => {
    var gamepads = navigator.getGamepads();
    console.log(gamepads);
});

function gameLoop(){
    const GamepadList = navigator.getGamepads();
    const gamepad = GamepadList[0];
    const nButtons = manette.buttons.length;
    const nAxes = gamepad.axes.length;

    for(let i = 0; i < nButtons; i++){
        if(gamepad.buttons[i].pressed){
            console.log("button pressed : ", i, "/", nButtons, "/ Value : ", gamepad.buttons[i].value);
        }
    }

    requestAnimationFrame(gameLoop);
}

It's working. But each time requestAnimationFrame is calling gameLoop, my four const are reset, Am I wrong ? So I tried to declare them with let keyword, out of everything, then to initialize them in the "gamepadconnected" event handler. And here is my issue !
When I click on a button, then release it, my script will be locked on this button, I'll have an increasing amount of "button pressed : 0 / 17 / Value : 1", and the script will ignore other buttons.
I can't understand this behavior, can someone explain it to me ?

Thanks

1

There are 1 answers

1
nondebug On

I think you have a bug, manette is not defined:

    const nButtons = manette.buttons.length;

I've uploaded a demo showing how you can generate your own custom events for gamepad buttons and axes:

https://github.com/nondebug/gamepad-event-source/blob/main/index.html

The editors of the Gamepad API spec have wanted to add gamepad input events for a while, see here for the relevant spec issue. I wrote a proposal here but it hasn't been adopted yet or implemented by any browsers.