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

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

François Beaufort
François Beaufort

使用鼠标或触控板在屏幕上移动指针时,加速移动是一项人体工学功能。它允许通过缓慢移动来精确移动,同时允许指针通过快速的快速移动穿过整个屏幕。具体而言,对于移动鼠标的相同物理距离,如果距离移动得更快,那么屏幕上的指针将移动得更远。

操作系统默认启用鼠标加速。对于某些第一方视角游戏(通常是第一人称射击游戏 [FPS]),原始鼠标输入数据用于在不进行加速调整的情况下控制相机旋转。相同的物理运动(慢或快)会导致相同的旋转。对专业游戏玩家而言,这样可以获得更出色的游戏体验和更高的准确度。

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

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

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

浏览器支持

  • 37
  • 13
  • 50
  • 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 审核本文。