监听游戏手柄连接和输入

Que*_*n3r 9 javascript gamepad-api

我想为我的 Web 应用程序提供游戏手柄支持。这个应用程序是一个套接字客户端(使用 socket.io),它也应该能够处理游戏手柄输入。

因此,当通过 USB 或蓝牙插入游戏手柄时,我想触发一个事件,输入也是如此。我希望Gamepad API能够解决它。不幸的是它没有。

我创建了这个例子

$(document).ready(() => {
  window.addEventListener("gamepadconnected", e => {
    console.log("connected gamepad");
  });

  window.addEventListener("gamepaddisconnected", e => {
    console.log("disconnected gamepad");
  });
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

我插入了我的 XBox360 控制器,但不幸的是没有触发任何事件。我错过了什么吗?

我在 Manjaro Linux(64 位)上使用 Chrome 版本 76.0.3809.132(官方版本)

navigator.getGamepads()在控制台中运行时,我得到了这个结果GamepadList {0: null, 1: null, 2: null, 3: null, length: 4}

顺便说一句。当然,我的控制器正在处理其他应用程序,例如游戏:)


更新

我安装了 Firefox 68.0.1(64 位)并且它工作了……但是 Chromium 似乎在挣扎

svi*_*gen 1

总长DR

  1. 循环刷新游戏手柄状态并构建您自己的事件。
  2. 提醒玩家按下游戏手柄上的按钮即可开始。

我用 Gamepad API 编写了一个小实验,并在 thepointless.com 上运行。完整的源代码可以在 Github 上找到

本质上,我的实验循环执行以下操作,并将输出打印到屏幕上:

JSON.stringify(
    [...navigator.getGamepads()]
    .filter(p => p)
    .map(pad => ({
        index: pad.index,
        id: pad.id,
        mapping: pad.mapping,
        axes: pad.axes,
        buttons: [...pad.buttons].map(b => ({
            pressed: b.pressed,
            touched: b.touched,
            value: b.value
        })),
        vibrationActuator: pad.vibrationActuator
    })),
    null,
    2
);
Run Code Online (Sandbox Code Playgroud)

在我的文章中,我注意到了一些我预计通常会对使用 API 有所帮助的事情。但是,与OP更相关的是:

  1. 事件监听器有点不可靠。
  2. navigator.getGamepads()在按下游戏手柄按钮之前,无法访问游戏手柄。
  3. 返回的游戏手柄对象navigator.getGamepads()不是“活动的”;您实际上需要重新获取它们以控制最新的轴和按钮状态。

出于这些原因,特别是因为您总是需要查询navigator.getGamepads()以刷新按钮/轴状态,所以我使用 API 所做的任何认真工作都将始终在游戏循环中重新查询游戏手柄,然后检查状态,并指示用户按如果找不到游戏手柄,请使用游戏手柄按钮。如果我需要“活动”,我会建立自己的活动。

我建议其他人也这样做。