Recreación de elementos de juego para la web: el deslizamiento de tarjeta entre nosotros

Como desarrollador web, presto mucha atención al diseño de videojuegos. Desde el HUD en Overwatch hasta la pantalla de captura en Pokémon Go y la caza en Oregon Trail, los juegos suelen tener mecánicas interesantes e interacciones satisfactorias , muchas de las cuales inspiran mis propios juegos de codificación en Codepip .

Más allá de eso, implementar pequeñas porciones de estos diseños de juegos en una pila web es una forma divertida y eficaz de ampliar sus habilidades. Al centrarse en un elemento específico, dedicas tu tiempo a trabajar en una parte interesante sin tener que construir un juego completo con todo lo que eso implica. E incluso en este ámbito limitado, a menudo queda expuesto a nuevas tecnologías y técnicas que traspasan los límites de su conocimiento de desarrollo.

Como caso de estudio para esta idea, lo guiaré a través de mi recreación del pase de tarjeta de Among Us . Para cualquiera que no sepa nada, Among Us es un popular juego multijugador. A bordo de una nave espacial, los compañeros de tripulación tienen que deducir quién de ellos es un impostor. Mientras tanto, completan tareas de mantenimiento mundanas y evitan que el impostor los ofenda.

Pasar la tarjeta es la más famosa de las tareas de mantenimiento. A pesar de ser simple, tantos jugadores han tenido problemas con él que se ha convertido en tema de transmisiones y memes.

Aquí está mi demostración

Esta es mi interpretación de la tarea de deslizar la tarjeta:

A continuación, le explicaré algunas de las técnicas que utilicé para crear esta demostración.

Deslizar con el mouse y eventos táctiles

Después de estructurar rápidamente los componentes principales en código, tuve que hacer que la tarjeta se pudiera arrastrar. En el juego, cuando empiezas a arrastrar la tarjeta, sigue la posición del puntero horizontalmente, pero permanece alineada con el lector de tarjetas verticalmente. La tarjeta tiene un límite en cuanto a la distancia que se puede arrastrar hacia la izquierda o hacia la derecha más allá del lector. Por último, cuando levanta el mouse o el dedo, la tarjeta vuelve a su posición original.

Todo esto se logra asignando funciones al mouse y eventos táctiles. Tres funciones son todo lo que se necesita para manejar el mouse hacia abajo, mover el mouse y subir el mouse (o tocar inicio, tocar mover y tocar finalizar si está en un dispositivo con pantalla táctil). Aquí está el esqueleto de ese código JavaScript:

const card = document.getElementById('card');const reader = document.getElementById('reader');let active = false;let initialX;// set event handlersdocument.addEventListener('mousedown', dragStart);document.addEventListener('mousemove', drag);document.addEventListener('mouseup', dragEnd);document.addEventListener('touchstart', dragStart);document.addEventListener('touchmove', drag);document.addEventListener('touchend', dragEnd);function dragStart(e) {  // continue only if drag started on card  if (e.target !== card) return;  // get initial pointer position  if (e.type === 'touchstart') {    initialX = e.touches[0].clientX;  } else {    initialX = e.clientX;  }  active = true;}function drag(e) {  // continue only if drag started on card  if (!active) return;  e.preventDefault();    let x;  // get current pointer position  if (e.type === 'touchmove') {    x = e.touches[0].clientX - initialX;  } else {    x = e.clientX - initialX;  }  // update card position  setTranslate(x);}function dragEnd(e) {  // continue only if drag started on card  if (!active) return;  e.preventDefault();    let x;  // get final pointer position  if (e.type === 'touchend') {    x = e.touches[0].clientX - initialX;  } else {    x = e.clientX - initialX;  }  active = false;    // reset card position  setTranslate(0);}function setTranslate(x) {  // don't let card move too far left or right  if (x  0) {    x = 0;  } else if (x  reader.offsetWidth) {    x = reader.offsetWidth;  }  // set card position on center instead of left edge  x -= (card.offsetWidth / 2);    card.style.transform = 'translateX(' + x + 'px)';}

Establecer estado conperformance.now()

A continuación, tuve que determinar si el pase de la tarjeta era válido o no válido. Para que sea válida, deberás arrastrar la tarjeta por el lector a la velocidad adecuada. ¿No lo arrastraste lo suficiente? Inválido. ¿Demasiado rapido? Inválido. ¿Demasiado lento? Inválido.

Para saber si la tarjeta se ha deslizado lo suficiente, verifiqué la posición de la tarjeta con respecto al borde derecho del lector de tarjetas en la función dragEnd:

let status;// check if card wasn't swiped all the wayif (x  reader.offsetWidth) {  status = 'invalid';}setStatus(status);

Para medir la duración del deslizamiento de la tarjeta, configuro las marcas de tiempo de inicio y finalización en dragStarty dragEndrespectivamente, usando performance.now().

function setStatus(status) {  // status is only set for incomplete swipes so far  if (typeof status === 'undefined') {    // timestamps taken at drag start and end using performance.now()    let duration = timeEnd - timeStart;    if (duration  700) {      status = 'slow';    } else if (duration  400) {      status = 'fast';    } else {      status = 'valid';    }  }  // set [data-status] attribute on reader  reader.dataset.status = status;}

Según cada condición, se establece un valor diferente en el data-statusatributo del lector. CSS se utiliza para mostrar el mensaje relevante e iluminar una luz roja o verde.

#message:after {  content: "Please swipe card";}[data-status="invalid"] #message:after {  content: "Bad read. Try again.";}[data-status="slow"] #message:after {  content: "Too slow. Try again.";}[data-status="fast"] #message:after {  content: "Too fast. Try again.";}[data-status="valid"] #message:after {  content: "Accepted. Thank you.";}.red {  background-color: #f52818;  filter: saturate(0.6) brightness(0.7);}.green {  background-color: #3dd022;  filter: saturate(0.6) brightness(0.7);}[data-status="invalid"] .red,[data-status="slow"] .red,[data-status="fast"] .red,[data-status="valid"] .green {  filter: none;}

Toques finales con fuentes, animaciones y audio.

Una vez completada la funcionalidad principal, agregué algunos toques más para que el proyecto se pareciera aún más a Among Us.

Primero, utilicé una fuente personalizada gratuita llamada DSEG para imitar el tipo segmentado de las pantallas LCD antiguas. Todo lo que hizo falta fue alojar los archivos y declarar la fuente en CSS .

@font-face {  font-family: 'DSEG14Classic';  src: url('../fonts/DSEG14-Classic/DSEG14Classic-Regular.woff2') format('woff2'),       url('../fonts/DSEG14-Classic/DSEG14Classic-Regular.woff') format('woff'),       url('../fonts/DSEG14-Classic/DSEG14Classic-Regular.ttf') format('truetype');}

A continuación, copié la animación de fluctuación del texto en el original. Los desarrolladores de juegos a menudo agregan animaciones sutiles para darle vida a un elemento, como hacer que un fondo se desvíe o que un personaje, bueno, respire. Para lograr el jitter, definí una animación CSS:

@keyframes jitter {  from {    transform: translateX(0);  }  to {    transform: translateX(5px);  }}

En este punto, el texto se desliza suavemente hacia adelante y hacia atrás. En cambio, lo que quiero es que salte hacia adelante y hacia atrás cinco píxeles a la vez. Ingrese la steps()función :

#message {  animation: jitter 3s infinite steps(2);}

Finalmente, agregué los mismos comentarios de audio que se usan en Among Us.

let soundAccepted = new Audio('./audio/CardAccepted.mp3');let soundDenied = new Audio('./audio/CardDenied.mp3');if (status === 'valid') {  soundAccepted.play();} else {  soundDenied.play();}

Los efectos de sonido suelen estar mal vistos en el mundo del desarrollo web. Un proyecto como este es una oportunidad para volverse loco con el audio.

Y con eso, ¡terminamos! Aquí está esa demostración nuevamente:

Prueba el tuyo propio

Dado lo estandarizada que se ha vuelto la web en apariencia, este enfoque de extraer un elemento de un juego e implementarlo para la web es una buena manera de salir de su zona de confort y probar algo nuevo.

Tome esta tarjeta magnética Among Us. En una demostración pequeña y sencilla, probé fuentes web y animaciones en CSS. Jugué con eventos de entrada y audio en JavaScript. Incursioné con un estilo visual poco convencional.

Ahora es el momento de que examines mecánicas interesantes de tus juegos favoritos y trates de replicarlas. Quizás te sorprenda lo que aprendas.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir