停用鼠标加速以提供更好的 FPS 游戏体验

Web 应用现在可以在捕获指针事件时停用鼠标加速度。

François Beaufort
François Beaufort

加速移动是一项人体工程学功能,可在使用鼠标或触控板移动屏幕上的指针时提供帮助。它既能通过缓慢移动实现精准移动,也能通过快速短促的动作让指针横跨整个屏幕。具体来说,在鼠标移动相同物理距离的情况下,如果移动速度更快,屏幕上的指针移动的距离就更远。

操作系统默认启用鼠标加速。对于某些第一人称视角游戏(通常是第一人称射击游戏 [FPS]),原始鼠标输入数据用于控制相机旋转,而无需调整加速度。无论物理运动是快还是慢,都会产生相同的旋转。专业游戏玩家表示,这有助于提升游戏体验并提高准确性。

Windows 10 设置中指针移动控制的屏幕截图。
Windows 10 设置中的指针移动控制。

从 Chrome 88 开始,借助更新后的 Pointer Lock API,Web 应用可以在加速和非加速鼠标移动数据之间来回切换。

Google StadiaNvidia GeForce Now 等基于网络的平台已在使用这些新功能来满足 FPS 游戏玩家的需求。

Browser Support

  • Chrome: 37.
  • Edge: 13.
  • Firefox: 50.
  • Safari: 10.1.

Source

使用此 API

请求指针锁定

指针锁定是指桌面应用隐藏指针图标并解释鼠标移动以用于其他用途(例如在 3D 世界中环顾四周)的规范术语。

mousemove 文档事件中的 movementXmovementY 属性会告知您自上次移动事件以来鼠标指针移动了多少。不过,当指针移出网页时,这些值不会更新。

document.addEventListener("mousemove", (event) => {
  console.log(`movementX: ${event.movementX} movementY: ${event.movementY}`);
});

捕获鼠标指针(或请求锁定指针)后,您无需再担心指针移出屏幕。这对于沉浸式网页游戏尤其有用。当指针被锁定后,所有鼠标事件都会发送到指针锁定的目标元素。

对目标元素调用 requestPointerLock() 以请求指针锁定,并监听 pointerlockchangepointerlockerror 事件以监控指针锁定状态的变化。

const myTargetElement = document.body;

// Call this function to request a pointer lock.
function requestPointerLock() {
  myTargetElement.requestPointerLock();
}

document.addEventListener("pointerlockchange", () => {
  if (document.pointerLockElement) {
    console.log(`pointer is locked on ${document.pointerLockElement}`);
  } else {
    console.log("pointer is unlocked");
  }
});

document.addEventListener("pointerlockerror", () => {
  console.log("pointer lock error");
});

停用鼠标加速

调用 requestPointerLock() 并使用 { unadjustedMovement: true } 来停用操作系统级鼠标加速调整,并访问原始鼠标输入。 这样一来,当指针锁定后,来自 mousemove 事件的鼠标移动数据就不会包含鼠标加速度。

使用 requestPointerLock() 返回的新 promise 来了解请求是否成功。

function requestPointerLockWithUnadjustedMovement() {
  const promise = myTargetElement.requestPointerLock({
    unadjustedMovement: true,
  });

  if (!promise) {
    console.log("disabling mouse acceleration is not supported");
    return;
  }

  return promise
    .then(() => console.log("pointer is locked"))
    .catch((error) => {
      if (error.name === "NotSupportedError") {
        // Some platforms may not support unadjusted movement.
        // You can request again a regular pointer lock.
        return myTargetElement.requestPointerLock();
      }
    });
}

您可以在加速和非加速鼠标移动数据之间切换,而无需释放指针锁定。只需使用所需的选项再次请求锁定指针即可。如果该请求失败,原始锁定将保持不变,并且返回的 promise 将拒绝。对于失败的更改请求,不会触发任何指针锁定事件。

浏览器支持

Pointer Lock API 在各种浏览器中均得到良好支持。不过,截至 2020 年 10 月,只有基于 Chromium 的浏览器(例如 Chrome、Edge 等)支持停用操作系统级鼠标加速度调整功能。 如需了解最新信息,请参阅 MDN 的浏览器兼容性表。

操作系统支持

ChromeOS、macOS Catalina 10.15.1 和 Windows 支持停用操作系统级鼠标加速度调整功能。Linux 随后也会支持。

示例

您可以运行示例来体验 Pointer Lock API。

实用链接

致谢

感谢 James HollyerThomas SteinerJoe MedleyKayce BasquesVincent Scheib 对本文的审核。