How to detect joystick events from the browser?

Asked

Viewed 49 times

0

Hello, whereas I have a joystick connected and running on my pc; How do I receive events from it through the browser? That’s possible?

I can detect keyboard events, only I wish my little game could be played with the controller (it’s done in HTML5 even).

  • It has such a Gamepad API, I have no idea that browsers support it, but the default exists, it even has a page for you to test: https://html5gamepad.com/

  • Good documentation on MDN. Picks up events when you press a joystick button.

1 answer

2

The event itself keydown takes the events of the buttons of some joysticks/controls, in case could enumerate them so:

document.addEventListener("keydown", function(event) {
      console.log(event.keyCode);
}, true);

So I would discover every code of every key, I can’t say that everyone will work, nor can I test.

Remember that there is a native API for this, the https://developer.mozilla.org/en-US/docs/Web/API/Navigator/getGamepads (https://w3c.github.io/gamepad/)

But it’s experimental, this being the case there is no guarantee that it will always be like this or that all browsers will support immediately

With the event gamepadconnected you know when the control is connected (example of MDN):

window.addEventListener("gamepadconnected", function(e) {
  var gp = navigator.getGamepads()[e.gamepad.index];
  console.log(
    "Gamepad connected at index %d: %s. %d buttons, %d axes.",
    gp.index, gp.id, gp.buttons.length, gp.axes.length
  );
});

You can also check at the beginning of the script when it starts if all indexed controls are connected without pressing anything on the button, remembering that the control was already connected before the page load the event gamepadconnected will only be fired if the user moves a "directional" (axis), then something as it must solve to detect what was connected:

var joys = navigator.getGamepads();

for (let i = 0, j = joys.length; i < j; i++) {
    if (joys[i].connected) console.log("Controle conectado: ", i);
}

Importantly, it’s experimental. You can also check if the control is disconnected: https://w3c.github.io/gamepad/#Event-gamepaddisconnected

window.addEventListener("gamepaddisconnected", function(e) {
  ...
});

Not documented if there is event to detect when you need a key, but basically a setTimeout would solve, something very simple as:

var listenJoysTimeout, connected = false;

var joys = navigator.getGamepads();

//Verifica se pelo menos um controle esta conectado
for (let i = 0, j = joys.length; i < j; i++) {
    if (joys[i].connected) {
         connected = true;
         break;
    }
}

if (connected) startGame();

window.addEventListener("gamepadconnected", startGame);

window.addEventListener("gamepaddisconnected", function (e) {
    //Só aceita o controle "1"
    if (e.gamepad.index != 0) return;

    if (listenJoysTimeout) clearTimeout(listenJoysTimeout);

    connected = false;
});


function listenJoys(joys)
{
     if (joys[0] && joys[0].connected) {
        let joy = joys[0]; //Aqui pegamos apenas o controle "1", mas seria possivel iterar e verificar todos

        for (let axe of joy.axes) {
            if (axe !== 0) console.log("direção (de -1.0 até 1.0)", axe);
        }

        //Teclas
        for (let button of joy.buttons) {
            if (button.pressed) console.log("Pressionado", button);
        }
     }

     setTimeout(listenJoys, 10, joys);//Executa novamente
}


function startGame(e)
{
    connected = true;

    if (listenJoysTimeout) clearTimeout(listenJoysTimeout);

    listenJoys(joys);
}

In this example I added only one control, but in general it is not complicated to evaluate several, what has to keep in mind is to know which is which, but ai goes beyond what was asked, because it will depend on the desired structure of your game.

In the https://w3c.github.io/gamepad/#Usage-examples talk to use requestAnimationFrame, but using it depends on understanding what you’re doing in your hypothetical game, it’s no use getting here I tell you that this is good practice, because it can be something so simple or you can create something that bars X situation that in general can end up becoming a problem, of course whether you built your game (animations and frames) with requestAnimationFrame then you probably already know how the control works on this, but getting into embedding it directly would not be a matter of good practice, it would be like "drive" if you know what is "brake" and "throttle", so it is better to work in parts.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.