我用 JavaScript 构建了手柄支持

我花了一个周末的时间,为一款浏览器游戏进行控制器输入的逆向工程。凌晨两点,我盯着一个空数组发呆,什么都没有显示出来。

这次经历比任何教程都让我对浏览器 API 和硬件轮询有了更深的理解。

Web 游戏正在蓬勃发展。随着 WebGL 和 WebGPU 的出现,浏览器游戏的质量已经达到了很高水准。玩家们期望插上 Xbox 或 PS5 控制器后能立即使用。

如果你正在开发游戏、无障碍工具或自定义仪表板,那么你需要了解 HTML5 Gamepad API。它在 Chrome、Firefox 和 Edge 中都能运行,且无需任何库。

以下是我学到的知识:

  • 该 API 的连接过程是事件驱动的,但输入过程是基于轮询的。
  • 你必须使用 requestAnimationFrame 来持续读取输入。
  • 在用户按下按钮之前,浏览器不会显示控制器。这是一种防止硬件指纹识别的隐私保护功能。

数据管理:

  • 使用 gamepad.mapping 来检查是否为“标准”布局。标准映射可以确保按钮 0 始终是底部的面部按钮。
  • 检查 gamepad.id 以获取厂商 ID (Vendor ID) 和产品 ID (Product ID)。这有助于你识别特定的硬件,例如 Sony DualSense。
  • 务必实现死区 (deadzone) 过滤器。摇杆永远不会处于完美的中心位置。如果没有死区设置,你的角色或摄像机将会不断漂移。

处理死区的一种简单方法: 如果 Math.abs(axis) > 0.1,则使用该值。

触觉反馈: 你可以使用 gamepad.vibrationActuator.playEffect 来触发震动。这在 Chrome 和 Edge 中表现良好。Firefox 提供部分支持,而 Safari 则不支持。

项目核心要点:

  • 监听 gamepadconnectedgamepaddisconnected 事件。
  • 追踪之前的按钮状态,以区分“按下 (press)”与“长按 (hold)”。
  • 使用死区阈值来忽略微小的摇杆移动。
  • 在多个浏览器上进行测试。
  • 请记住 navigator.getGamepads() 返回的是一个快照。你必须在循环内部调用它才能获取最新数据。

如果你想在编写代码之前测试硬件,可以使用 GamepadTester.pro。它能实时显示原始 API 数据和轴值。

出处:https://dev.to/grezalazar23453/i-built-gamepad-support-into-my-web-app-using-pure-javascript-heres-everything-i-learned-51a5