Uso de la API de Gamepad en juegos web
Muchos géneros de juegos, como los de carreras y de lucha de plataformas, dependen de un gamepad en lugar de un teclado y un mouse para obtener la mejor experiencia. Esto significa que estos juegos ahora se pueden jugar en la web con los mismos mandos que se utilizan para las consolas. Hay una demostración disponible y, si no tienes un gamepad, aún puedes disfrutar de la demostración usando un teclado. Como ocurre con todas las tecnologías experimentales, los resultados con la API de Gamepad son inestables. Sin embargo, al usarlo (y brindar retroalimentación), estás esculpiendo el futuro de la tecnología. ¡Esto representa una gran oportunidad para la industria del juego!
La API de Gamepad es una tecnología relativamente nueva que nos permite acceder al estado de los gamepads conectados mediante JavaScript, lo cual es una gran noticia para los desarrolladores de juegos HTML5.
Muchos géneros de juegos, como los de carreras y de lucha de plataformas, dependen de un gamepad en lugar de un teclado y un mouse para obtener la mejor experiencia. Esto significa que estos juegos ahora se pueden jugar en la web con los mismos mandos que se utilizan para las consolas.
Hay una demostración disponible y, si no tienes un gamepad, aún puedes disfrutar de la demostración usando un teclado.
Retroceso del teclado
También hay aplicaciones como Joypad y Ultimate Gamepad que te permiten conectar un teléfono inteligente a la computadora a través de una aplicación "receptora". Las aplicaciones del receptor simulan la entrada del teclado, a diferencia de un gamepad.
¿Qué mandos funcionan?
Cualquier gamepad que el sistema operativo entienda como un dispositivo XInput o DirectInput funcionará con la API de Gamepad. Es posible hacer que funcionen otros controladores de consola, pero eso requeriría convertidores de hardware o software adicional.
Debido a que esta API es relativamente nueva y experimental, la compatibilidad del navegador es limitada y la documentación del W3C aún es un borrador en funcionamiento.
Sin embargo, la implementación del navegador está por encima del 50% , lo que incluye todos los navegadores principales. La API incluso se está abriendo camino en el mundo móvil, siendo Chrome para Android el primer navegador móvil que la admite.
En el navegador Wii U de Nintendo, se puede acceder al gamepad de Wii U. Desafortunadamente, Nintendo aún no ha implementado la API Gamepad; en cambio, el dispositivo tiene su propia propiedad en la ventana ( window.wiiu.gamepad) y almacena los estados de sus botones como valores hexadecimales, con indicadores específicos para cada botón.
Detección de características
Podemos comprobar si un navegador admite la API de Gamepad con este fragmento:
if(!!navigator.getGamepads){ // Browser supports the Gamepad API}
Leyendo los estados del gamepad
Los Gamepadestados son accesibles con:
var gamepads = navigator.getGamepads();
Actualmente, en Chrome y Opera, esto devolverá GamepadListhasta cuatro Gamepadobjetos.
GamepadList {0: Gamepad, 1: Gamepad, 2: undefined, 3: undefined}
Firefox, en cambio, devuelve un JavaScript Arrayde Gamepads, que, en teoría, es infinito. (He tenido nueve gamepads conectados al mismo tiempo).
Array [ Gamepad, Gamepad ]
Votación
Podemos sondear los Gamepadestados usando requestAnimationFrame. Dependiendo de la cantidad de gamepads que quieras admitir, esto aumentará la complejidad de cómo usas los Gamepadestados. Si desea admitir solo un gamepad, puede sondear el primer gamepad de la colección de la siguiente manera:
var gamepad = navigator.getGamepads()[0];
Esto significa que tomará el primer gamepad que esté conectado o, si todos los gamepads ya están conectados, el primer gamepad en el que se presione un botón.
Cada GamepadBbject se ve así:
axes: Array[4]buttons: Array[16]connected: trueid: "Xbox 360 Controller (XInput STANDARD GAMEPAD)"index: 0mapping: "standard"timestamp: 12
Este es el Gamepadobjeto de un controlador Microsoft Xbox 360 para Windows .
Nota: No ides consistente en todos los navegadores. Por ejemplo, está 45e-28e-Wireless 360 Controlleren Mozilla Firefox , que es diferente de lo que Google Chrome proporciona anteriormente.
Información
| Propiedad | Descripción |
|---|---|
connected |
Este es un booleano que indica la conectividad del gamepad. |
id |
Esta cadena contiene información de identificación sobre el gamepad. |
index |
Este es un número entero único que se incrementa automáticamente para cada gamepad. |
mapping |
Esta cadena nos indica si el navegador ha reasignado el dispositivo a un diseño conocido. |
timestamp |
Esto aumenta cuando cambia el estado del dispositivo. Algunos dispositivos sondean constantemente, lo que significa que la marca de tiempo aumenta constantemente. |
axes |
Se trata de una colección de números que representan el estado de cada palanca o botón analógico. |
buttons |
Esta colección de objetos representa el estado de cada botón. |
ejes
En los gamepads que tienen joysticks analógicos, la axesmatriz contendrá números que oscilan entre un mínimo y un máximo para cada eje, normalmente -1y 1.
Aplicar una zona muerta
Debido a que la palanca analógica varía entre -1y 1, si la palanca no se toca y está en su posición central, entonces, teóricamente, el valor debería ser 0. Sin embargo, este no siempre es el caso de los controladores o gamepads baratos que están desgastados o dañados o que tienen joysticks "movibles" (sí, ese gamepad que tu amigo siempre intenta regalarte).
Una “zona muerta” es un umbral que se utiliza para evitar que se utilicen valores inferiores a cierta cantidad para controlar el juego.
La siguiente función aplica una zona muerta. El umbral también se resta de cualquier valor por encima del umbral, de modo que el valor en el umbral sea 0, en lugar de un repentino 0,25, por ejemplo.
var applyDeadzone = function(number, threshold){ percentage = (Math.abs(number) - threshold) / (1 - threshold); if(percentage 0) percentage = 0; return percentage * (number 0 ? 1 : -1);}
Se puede utilizar así:
var joystickX = applyDeadzone(gamepad.axes[0], 0.25);
Esto ignora los valores entre -0,25 y +0,25 y calcula el porcentaje decimal, teniendo en cuenta el umbral dado. Si aplicaras esto a los ejes x e y, obtendrías una zona muerta que se parece a esta cuando se representa gráficamente:
Nota: Los ejes no siempre son analógicos. Algunos controladores alternarán entre valores. Por ejemplo, algunos botones direccionales alternan entre un valor máximo, mínimo y central para cada eje, -1como 0y 1.
Botones
Para la buttonsmatriz, GamepadButtonse proporciona un objeto para cada elemento. En la mayoría de los casos, la valuepropiedad se correlaciona directamente con la pressedpropiedad. Por ejemplo, valuealternará entre 0y 1porque pressedalterna entre falsey true.
Botón liberado
GamepadButton pressed: false value: 0
Botón presionado
GamepadButton pressed: true value: 1
Botones analógicos
La mayoría de los gamepads de séptima generación (como el controlador Xbox 360) tienen botones analógicos, como los gatillos izquierdo y derecho. En este caso, valueoscilará entre 0 y 1, respectivamente. Aunque pressedfunciona, no se recomienda usarlo para botones no digitales; en su lugar, utilice un umbral contra value, que podría ser tan simple como este:
if(gamepad.buttons[7].value 0.5){ // FIRE!}
Nota: Debido a que el botón también es analógico, es posible que también sea necesario aplicar aquí una zona muerta.
Diferentes diseños
Cada controlador es diferente, lo que significa que la longitud del axesy buttonsvariará; Esto también se aplica a diferentes convertidores y/o controladores de conexión. Según la especificación, los navegadores deben mapear axesy buttonslo más cerca posible del " gamepad estándar " sugerido. No todos los gamepads tendrán todos estos botones; Los botones faltantes aparecerán en un estado no presionado (para botones) o en estado neutral (para ejes) en el objeto. Agregar un área de "configuración de control" a tu juego sería una buena idea si planeas admitir gamepads extraños y maravillosos, dando a los jugadores la libertad de configurar su gamepad como quieran y brindando a los usuarios con diferentes gamepads la oportunidad de asignar manualmente sus controles a tu juego.
Controlador Microsoft Xbox 360 para Windows
Controlador NES
Este es el diseño de un controlador NES original, que utiliza un convertidor de 15 pines a USB (el diseño puede variar según el fabricante). Este en particular utiliza ejes para entrada direccional, en lugar de botones.
Memoria USB y almohadilla Saitek SP550
Tiene 12 botones (14 en el dispositivo, y los dos gatillos tienen la misma funcionalidad que el gatillo y el botón del pulgar del joystick) y tres ejes (el tercer eje es el control deslizante del acelerador al lado del joystick). La parte del joystick del controlador se puede desmontar, dejando solo el pad. Al hacer esto, se desconectará el controlador y se volverá a conectar como un controlador diferente, lo que significa que los detalles sobre el Gamepadobjeto devuelto también cambiarán: cambiará idde SP550 Stick Pad Combo (Vendor: 06a3 Product: 100a)a SP550 Pad (Vendor: 06a3 Product: 100b)y el diseño también será diferente. En el modo “stick and pad”, el pad direccional está en la buttonsmatriz (cuatro botones), pero en el modo “pad”, el pad direccional está en la axesmatriz (dos ejes).
Controlador N64
Este es uno de mis controladores favoritos, principalmente por la nostalgia, no por la ergonomía.
Nintendo Wiimote y Nunchuck
Con estos controladores, era posible utilizar Wiimote y Nunchuk con la API Gamepad. Diferentes controladores darán como resultado diferentes diseños.
Para Windows , consulte " HID Wiimote: un controlador de dispositivo de Windows para el control remoto de Nintendo Wii " de Julian Löhr .
Para Mac , consulte Wjoy , un controlador de Nintendo Wiimote para Mac OS X.
Charlie J. Walter tiene una demostración de Wiimote, que sólo funciona con el controlador de Windows.
Para esta demostración, creé una función de calibración , porque los conductores piensan que la posición neutral (punto muerto) del giroscopio Wiimote es el valor cuando el controlador está conectado. Esto significa que debe conectar el controlador cuando esté sobre una superficie plana. Sin embargo, puede recalibrar el controlador con bastante facilidad leyendo el valor del giroscopio (un valor en axes) cuando el controlador está sobre una superficie plana, y luego almacenando ese valor y restándolo de cualquier lectura adicional.
Eventos
La API de Gamepad viene con dos eventos de ventana, gamepadconnectedy gamepaddisconnected, que se activan al conectarse y desconectarse, respectivamente. El usuario debe presionar un botón en el gamepad conectado para que gamepadconnectedse reconozca un evento. El objeto relevante Gamepadestá disponible en ambos objetos de evento con e.gamepad.
Eventos de conexión
window.addEventListener("gamepadconnected", function(e) { // Gamepad connected console.log("Gamepad connected", e.gamepad);});
window.addEventListener("gamepaddisconnected", function(e) { // Gamepad disconnected console.log("Gamepad disconnected", e.gamepad);});
Eventos de cambio de estado
Los eventos de cambio de estado aún no se han incluido en la especificación y requieren más discusión. Sin embargo, Firefox ya tiene tres eventos de cambio de estado gamepadbuttondown: gamepadbuttonupy gamepadaxismove. Estos nombres de eventos adoptan una convención de nomenclatura similar a la de los eventos de teclado y mouse. (Otras sugerencias incluyen gamepadchangedy gamepadaxischanged).
window.addEventListener("gamepadbuttondown", function(e){ // Button down console.log( "Button down", e.button, // Index of button in buttons array e.gamepad );});window.addEventListener("gamepadbuttonup", function(e){ // Button up console.log( "Button up", e.button, // Index of button in buttons array e.gamepad );});
Nota: actualmente, estos eventos solo funcionan en Firefox.
window.addEventListener("gamepadaxismove", function(e){ // Axis move console.log( "Axes move", e.axis, // Index of axis in axes array e.value, e.gamepad );});
Nota: Actualmente, este evento solo funciona en Firefox Nightly.
Usando la API en un juego
Independientemente de cómo renderices tu juego, puedes obtener el estado del gamepad en cada bucle del juego y aplicarlo a una entidad controlable. A continuación se muestra una demostración muy simple donde se aplica valueof axes[0]a la leftpropiedad CSS.
Vea la demostración del elemento DOM de Pen Gamepad API de Charlie Walter ( @cjonasw ) en CodePen .
Por supuesto, un juego complejo sería muy exigente, por lo que este enfoque probablemente no sea la mejor idea. En su lugar, puede utilizar WebGL o Canvas o utilizar una biblioteca de renderizado como Three.js o Babylon.js . Si el elemento no se mueve, entonces su controlador probablemente esté asignado de manera diferente. Esto significa que axes[0]no representa el joystick o el botón analógico que estás moviendo o simplemente no está asignado en absoluto; Intente cambiar axes[0]a otro elemento de la matriz. HTML5 Gamepad Tester tiene un desglose visual de los gamepads conectados y sus propiedades.
Configuración de control y problemas de mapeo
Las diferencias de mapeo se pueden solucionar con una utilidad de "configuración de control", como se muestra en la demostración de Charlie J. Walter.
Cómo funcionan las configuraciones de control de la demostración
En la demostración, el usuario hace clic en un cuadro de entrada relacionado con su gamepad y el control que desea cambiar o reasignar. El estado del gamepad se almacena y se compara constantemente con el estado actual de ese gamepad hasta que un eje o botón haya cambiado más que 0.5su estado almacenado. En ese momento, sabremos qué entrada quiere usar el usuario para esa acción del juego (por ejemplo, "izquierda", "derecha", "saltar") y la forma en que quiere usarla para representar esa acción del juego. La razón por la que digo esto es porque las acciones "izquierda" y "derecha" probablemente estarán en el mismo eje, pero el usuario usará el joystick de una manera ligeramente diferente para representar una acción diferente (por ejemplo, mover el joystick hacia la izquierda). para izquierda y moviéndolo de derecha a derecha). Esto se puede resolver usando el estado almacenado del botón modificado (pero redondeado, de modo que sea -1, 0o 1) para representar el estado mínimo de la acción del juego, y usando el estado nuevo (también redondeado) como su máximo. Estos estados se reducen a la mitad para buttonslos umbrales, siendo el resultado -0.5, 0o 0.5.
Cómo proporcionar un respaldo de teclado
Los eventos de ventana onkeydowny onkeyupfacilitan el suministro de un teclado alternativo. Podríamos agregar el código para hacer que el jugador haga algo en estos eventos, pero debido a que estamos leyendo el eachbucle del gamepad y usando las matrices axesy buttonsdel gamepad para luego hacer que el jugador haga algo, ponerlo aquí también tiene sentido. También significa menos código duplicado.
Una forma de hacer esto es tener una keyscolección para almacenar las claves actuales, que se actualiza con onkeydowny onkeyup, respectivamente.
Luego podemos realizar comprobaciones sencillas en el bucle del juego para activar al jugador.
// If right key downif(keys[39]){ // Move player right}
Terminando
Como ocurre con todas las tecnologías experimentales, los resultados con la API de Gamepad son inestables. Sin embargo, al usarlo (y brindar retroalimentación), estás esculpiendo el futuro de la tecnología.
Esto representa una gran oportunidad para la industria del juego. Muchos juegos ya utilizan tecnologías front-end como NW.js para crear aplicaciones nativas; combinarlos con la API de Gamepad creará juegos con una experiencia casi nativa. Sin embargo, este es sólo un elemento de una plataforma de juegos en rápido crecimiento. Las tecnologías web ahora son capaces de muchas de las funciones que vemos en los juegos nativos, incluida la manipulación de audio (a través de Web Audio API), entrada de movimiento del mouse sin restricciones de pantalla (a través de Pointer Lock API), gestos táctiles (a través de Touch Event API). y muchos más.
En el futuro, espero que la API del Gamepad pueda acceder a elementos como el ruido, el altavoz interno, el micrófono y otras entradas.
Para contribuir al futuro de la API, participe en debates y anuncie errores cuando los encuentre en un navegador determinado. ¡Me encantaría escuchar lo que creas con él!
Otras lecturas
- Cómo diseñar un juego móvil con HTML5
- Creación de un juego WebGL multiplataforma con Babylon.js
- Reconstrucción de un juego HTML5 en Unity
- Lo que los diseñadores web pueden aprender de los videojuegos
(ds, ml, al, jb, mrn)Explora más en
- Codificación
- javascript
- Juegos
- HTML5

Deja un comentario