Inhabilita la aceleración del mouse para brindar una mejor experiencia de juego FPS

Las apps web ahora pueden inhabilitar la aceleración del mouse cuando se capturan eventos del puntero.

François Beaufort
François Beaufort

El movimiento acelerado es una función ergonómica cuando se usa un mouse o un panel táctil para mover el puntero en la pantalla. Permite un movimiento preciso, ya que se mueve lentamente y, al mismo tiempo, permite que el puntero cruce toda la pantalla con un movimiento corto y rápido. Específicamente, para la misma distancia física que mueves el mouse, el puntero en pantalla se desplaza más si la distancia se recorre más rápido.

Los sistemas operativos habilitan la aceleración del mouse de forma predeterminada. En algunos juegos de perspectiva de origen, por lo general, de disparos en primera persona (FPS), se usan datos de entrada sin procesar del mouse para controlar la rotación de la cámara sin un ajuste de aceleración. El mismo movimiento físico, lento o rápido, genera la misma rotación. Esto se traduce en una mejor experiencia de juego y una mayor precisión, según los jugadores profesionales.

Captura de pantalla del control de movimiento del puntero en la configuración de Windows 10.
Control de movimiento del puntero en la configuración de Windows 10.

A partir de Chrome 88, las aplicaciones web pueden alternar entre los datos de movimiento del mouse acelerados y no acelerados gracias a la API actualizada de Pointer Lock.

Las plataformas de videojuegos basadas en la Web, como Google Stadia y Nvidia GeForce Now, ya usan estas funciones nuevas para complacer a los gamers de FPS.

Navegadores compatibles

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

Origen

Cómo usar la API

Cómo solicitar un bloqueo del puntero

Un bloqueo del puntero es el término canónico para el que una aplicación de escritorio oculta el ícono del puntero e interpreta el movimiento del mouse para otra cosa, p.ej., mirar un mundo en 3D.

Los atributos movementX y movementY de los eventos del documento mousemove te indican cuánto se movió el puntero del mouse desde el último evento de movimiento. Sin embargo, no se actualizan cuando el puntero se mueve fuera de la página web.

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

Capturar el puntero del mouse (o solicitar un bloqueo del puntero) te permite no preocuparte por que el puntero se mueva hacia afuera. Esto es particularmente útil para los juegos web envolventes. Cuando el puntero está bloqueado, todos los eventos del mouse van al elemento de destino del bloqueo del puntero.

Llama a requestPointerLock() en el elemento de destino para solicitar un bloqueo del puntero y escucha los eventos pointerlockchange y pointerlockerror para supervisar los cambios de bloqueo del puntero.

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");
});

Inhabilitar la aceleración del mouse

Llama a requestPointerLock() con { unadjustedMovement: true } para inhabilitar el ajuste a nivel del SO para la aceleración del mouse y acceder a la entrada sin procesar del mouse. De esta manera, los datos de movimiento del mouse de los eventos mousemove no incluirán la aceleración del mouse cuando el puntero esté bloqueado.

Usa la nueva promesa que muestra requestPointerLock() para saber si la solicitud se realizó de forma correcta.

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();
      }
    });
}

Es posible alternar entre datos de movimiento del mouse acelerado y no acelerado sin soltar el bloqueo del puntero. Solo debes volver a solicitar el bloqueo del puntero con la opción deseada. Si esa solicitud falla, la cerradura original permanecerá intacta y se rechazará la promesa que se muestra. No se activarán eventos de bloqueo del puntero para una solicitud de cambio que falló.

Navegadores compatibles

La API de Pointer Lock es muy compatible con todos los navegadores. Sin embargo, a partir de octubre de 2020, los navegadores basados en Chromium (p.ej., Chrome, Edge, etc.) son los únicos que admiten la inhabilitación del ajuste a nivel del SO para la aceleración del mouse. Consulta la tabla Compatibilidad del navegador de MDN para ver las actualizaciones.

Compatibilidad con el sistema operativo

La inhabilitación del ajuste a nivel del SO para la aceleración del mouse es compatible con ChromeOS, macOS Catalina 10.15.1 y Windows. Linux también lo hará.

Muestra

Para jugar con la API de Pointer Lock, ejecuta el ejemplo en Glitch. Asegúrate de consultar el código fuente.

Vínculos útiles

Agradecimientos

Gracias a James Hollyer, Thomas Steiner, Joe Medley, Kayce Basques y Vincent Scheib por revisar este artículo.