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, produce 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 apps web pueden alternar entre datos de movimiento del mouse acelerado y no acelerado gracias a la API actualizada de bloqueo del puntero.

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

Navegadores compatibles

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

Origen

Usar la API

Cómo solicitar un bloqueo del puntero

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

Los atributos movementX y movementY de los eventos de documentos mousemove te indican cuánto se movió el puntero del mouse desde el último evento de movimiento. Sin embargo, estos 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 en el 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ó correctamente.

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 solicita el bloqueo del puntero nuevamente 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 bloqueo del puntero es compatible con todos los navegadores. Sin embargo, los navegadores basados en Chromium (p.ej., Chrome, Edge, etc.) son los únicos que admiten inhabilitar el ajuste a nivel del SO para la aceleración del mouse a partir de octubre de 2020. Consulta la tabla Compatibilidad con navegadores de MDN para ver las actualizaciones.

Compatibilidad con el sistema operativo

Inhabilitar el ajuste a nivel del SO para la aceleración del mouse es compatible con ChromeOS, macOS Catalina 10.15.1 y Windows. Luego, se agregará Linux.

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.