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

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

François Beaufort
François Beaufort

加速移动是一项符合人体工学设计的功能,可让您使用鼠标或触控板在屏幕上移动指针。它允许通过缓慢移动实现精确移动,同时也允许指针通过快速短动作穿越整个屏幕。具体而言,对于您移动鼠标的相同物理距离,如果移动速度更快,屏幕上的指针会移动更远。

默认情况下,操作系统会启用鼠标加速功能。对于某些第一方视角游戏,通常是第一人称射击游戏 (FPS),会使用原始鼠标输入数据控制相机旋转,而无需进行加速调整。相同的物理运动(无论是缓慢还是快速)都会产生相同的旋转。据专业游戏玩家称,这可以带来更好的游戏体验和更高的准确性。

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

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

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

浏览器支持

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

来源

使用此 API

请求指针锁定

指针锁定是一个规范化术语,表示桌面应用隐藏指针图标并将鼠标动作解读为其他内容,例如在 3D 世界中环顾四周。

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

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

捕获鼠标指针(或请求指针锁定)后,您就不必再担心指针会移出界面。这对于沉浸式 Web 游戏特别有用。指针锁定时,所有鼠标事件都会转到指针锁定的目标元素。

对目标元素调用 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");
});

停用鼠标加速

使用 { unadjustedMovement: true } 调用 requestPointerLock() 可停用操作系统级鼠标加速调整,并访问原始鼠标输入。这样一来,当指针处于锁定状态时,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 版本将随后推出。

示例

您可以在 Glitch 上运行示例,以便使用 Pointer Lock API。请务必查看源代码

实用链接

致谢

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