paint-brush
Reviva algo de nostalgia: recreando el juego de la serpiente utilizando la API Canvas de HTML5 y JavaScriptby@ssaurel
500
500

Reviva algo de nostalgia: recreando el juego de la serpiente utilizando la API Canvas de HTML5 y JavaScript

Sylvain Saurel8m2024/01/21
Read on Terminal Reader

El Juego de la Serpiente es uno de los grandes clásicos de los años 90 en los móviles Nokia. Este tutorial le muestra cómo recrearlo en HTML5.
featured image - Reviva algo de nostalgia: recreando el juego de la serpiente utilizando la API Canvas de HTML5 y JavaScript
Sylvain Saurel HackerNoon profile picture
0-item
1-item

Si nunca has jugado al famoso juego de la Serpiente , ¡levanta la mano!


Lo digo, pero supongo que hoy en día la nueva generación quizá nunca haya oído hablar de este juego, que puede parecer un poco anticuado dadas las posibilidades que ofrecen los ordenadores y la Web actuales.


Y, sin embargo, hubo un tiempo en el que el juego Snake era un juego al que todos los propietarios de teléfonos móviles pasaban una cantidad excesiva de tiempo jugando. Sí, en aquel entonces no hablábamos de smartphones, sólo de teléfonos.


Era una buena época, como dice el refrán, y Nokia popularizó el juego a través de sus dispositivos móviles, que también fueron un referente. Hoy en día, no queda mucho del dominio de Nokia en el mundo móvil y del juego Snake.


Para aquellos que sienten nostalgia por este juego (y yo soy uno de ellos, debo admitirlo), este tutorial les enseñará cómo recrearlo para la Web. Para hacerlo, usaré la API Canvas de HTML5 y JavaScript.


También es una oportunidad para aprender a utilizar clases en Javascript y crear un bucle de juego eficaz para juegos web.

Creando la página web para nuestro juego Snake

Para empezar, vamos a crear la página web que nos permitirá jugar el juego Snake que desarrollaremos en este tutorial. Pronto comprobarás que esta página Web no presenta dificultad alguna. Dos divs, uno para el título de la página y otro para mostrar el área donde se moverá la serpiente.


A esto, agregaré un poco de CSS para centrar estos divs aplicándoles un ancho fijo:

Diseño de la clase Serpiente.

Como expliqué en la introducción de este tutorial, usaré una clase Snake dedicada para modelar el juego. Esto también te permitirá descubrir cómo manipular clases en JavaScript.


Nuestra Serpiente tendrá las siguientes propiedades:

  • bw y bh para representar el tamaño del tablero en ancho y alto respectivamente.
  • nbx y nby representan el número de celdas disponibles para el tablero.
  • eltw y elth para representar el tamaño de un elemento serpiente en ancho y alto.
  • dirx y diry que representan el vector de desplazamiento de la serpiente.
  • marginx y marginy agregan un pequeño margen al ancho y alto de los elementos de serpiente para que el jugador pueda ver la demarcación entre cada elemento de serpiente.
  • keyup , keydown , keyleft , keyright que almacenan el estado de las flechas en movimiento en un momento dado.
  • startftps almacena la cantidad de fotogramas por segundo necesarios para mover la serpiente al comienzo del juego.


Al final del constructor, se llama a un método init para inicializar la serpiente al comienzo del juego. Cuando vayas a iniciar un nuevo juego, simplemente vuelve a llamar a este método de inicio.


Esto nos da el siguiente código para nuestra clase Snake:

En el método init, puedes definir otras propiedades de la serpiente, como un puntero a su cabeza y un puntero a su cola. La matriz de elementos almacenará todos los elementos de la serpiente en un momento dado. La propiedad de puntos se usa para almacenar puntos para el juego actual, mientras que la propiedad de nivel se usa para definir cuántos puntos se acumulan para aumentar los fps del juego. Cuanto mayor sea el número de fps, más rápido se moverá la serpiente.


Dado que la propiedad fps representa el número de fotogramas por segundo, necesitamos tener una propiedad fpsinterval valorada como el resultado de dividir 1 segundo (o 1000 milisegundos) por el número deseado de fps.

El principio del juego de la serpiente.

El principio del juego de la Serpiente es sencillo: debes guiar a la serpiente utilizando las cuatro flechas direccionales para que se coma el máximo número de manzanas que aparecen en el tablero. Cada vez que comes una manzana, la serpiente crece en un elemento. A medida que la serpiente crece, te resultará difícil evitar tocar su propia cola. Si no lo haces, perderás y la puntuación comenzará de nuevo desde cero. Por supuesto, cada vez que comes una manzana, sumas un punto.


Vale la pena señalar que la versión de Snake que vamos a implementar es aquella en la que tocar los bordes del tablero no te hace perder. Simplemente te hace caer hacia el lado opuesto. Nokia implementó la segunda versión del juego Snake de esta manera.


Como la serpiente tiene que comerse una manzana, debemos mostrar esta manzana en el tablero de forma aleatoria, teniendo cuidado de no generar una manzana directamente sobre un elemento de la serpiente.


Esto nos da el siguiente método generatefood para nuestra clase Snake:

Representación de serpiente en pantalla

Nuestra clase Snake está progresando y ahora necesitamos crear un método para representar la serpiente en la pantalla. También necesitaremos mostrar el número de puntos del jugador en un momento determinado y, finalmente, mostrar la manzana a comer. La posición de la manzana se almacena en la propiedad alimentaria de la clase Serpiente.


Para representar la Serpiente en la pantalla, estoy usando la API Canvas de HTML5.


Usaré las primitivas de dibujo de esta API para dibujar rectángulos que representen los diversos elementos de la serpiente y la manzana que se va a comer. Aplicaré un color diferente a la manzana y a la serpiente para que el jugador pueda distinguirlas.


Esto proporciona el siguiente código para el método de dibujo de nuestra clase Snake:

Moviendo la serpiente

Ahora tenemos una serpiente que podemos mostrar en pantalla. Todo esto está muy bien, pero necesitamos agregar apoyo al movimiento de la serpiente. Como se explicó anteriormente, la serpiente se mueve a lo largo del vector de coordenadas (dirx, diry). Entonces, cada vez que llamamos al método de movimiento que voy a definir aquí, la serpiente se moverá en la misma cantidad.


En este método de movimiento comprobamos que las coordenadas de la cabeza de la serpiente corresponden a las de la manzana a comer. Si es así, la serpiente acaba de comerse la manzana. El jugador gana un punto, pero lo más importante es que debemos realizar cuatro acciones:


  1. Agrega un elemento a los elementos de la serpiente. Este elemento se convierte en la nueva cola.
  2. Genere una nueva manzana llamando a generatefood.
  3. Añade un punto al jugador.
  4. Si el jugador pasa un nivel, actualizamos el número de cuadros por segundo que se mostrarán para acelerar el movimiento de la Serpiente.


Aún así, en el método de movimiento, debemos comprobar que el jugador no ha cometido el error de tocar un elemento de la serpiente con la cabeza. Si este es el caso, ¡el juego se pierde y empezamos de nuevo! Para hacer esto, llamamos al método init de la clase Snake presentada anteriormente.


Ahora, necesitamos completar el método de movimiento moviendo la serpiente. Para hacer esto, agregamos dirx y diry a las coordenadas de la cabeza de la serpiente. Esto nos da una nueva cabeza que agregar. También notarás que mover la serpiente se hace de manera inteligente quitando la cola cada vez y agregando una nueva cabeza. Esto evita tener que actualizar la posición de todos los elementos de la serpiente.


Termine recordando actualizar el nuevo encabezado. Por cierto, también habrás notado que cuando la cabeza de la serpiente cruza un límite del tablero, hacemos que se mueva hacia el lado opuesto del tablero. Esto se aplica tanto al ancho como al largo.


Esto nos da el siguiente código para el método de movimiento:

El GameLoop de nuestro Juego de Serpientes

Nuestra Serpiente se puede mostrar en pantalla. Nuestra Serpiente se puede mover llamando a su método de movimiento. ¿Qué nos falta?


¡Nos falta la implementación del GameLoop de nuestro juego!


Sin este GameLoop, que llamará a los métodos de movimiento y sorteo a intervalos regulares, Snake no podrá moverse. A continuación, le mostraremos cómo implementar un GameLoop de la manera correcta en JavaScript, dejando que el navegador lo llame cuando lo considere oportuno para no bloquear el hilo de renderizado de la página web del juego.


Para hacer esto, usaremos el método requestAnimationFrame de la ventana de objetos JavaScript estándar. Luego, el navegador adaptará los fps máximos que puede admitir al ordenador o teléfono inteligente en el que se utilizará la página web.


Dentro de nuestro método de bucle de juego, luego descorrelacionaremos la cantidad de fps admitidos por el navegador de la cantidad de fps que queremos mover nuestra serpiente. Sólo llamaremos a los métodos mover y dibujar cuando estemos dentro del rango de fps definido anteriormente.


Es importante actualizar las coordenadas del vector de movimiento de la serpiente según el estado de las cuatro teclas de dirección: arriba, abajo, izquierda y derecha.


Finalmente llamamos al GameLoop, delegando al navegador la tarea de elegir el mejor momento para hacerlo. Esto nos da el siguiente código para GameLoop:

Manejo de la interacción del usuario con Snake

Para permitir que la Serpiente se mueva de acuerdo con las teclas direccionales presionadas por el jugador, usamos los eventos keydown y keyup. Para cada uno de estos eventos, llamaremos a un método de la clase Snake. Lógicamente, esto será presionar hacia abajo para el evento de tecla y presionar hacia arriba para el evento de tecla.


Actualizamos el valor de las propiedades de la clase Snake vinculadas de acuerdo con lo que hace el jugador con estas claves. Como puedes ver, no bloqueamos el juego actualizando directamente la posición de la serpiente. En su lugar, actualizamos el estado en el método gameloop, que se llama a intervalos regulares.

Montaje de los distintos componentes del Snake

Para completar este juego de Snake, necesitamos ensamblar los distintos elementos. Recuperamos el objeto Canvas a través de su ID. Luego, obtenemos el contexto 2D vinculado a este Canvas. Aplicar las dimensiones deseadas. Creamos un objeto Snake, pasando los distintos valores esperados como parámetros, incluido el número de celdas del tablero.


Agregue los detectores de eventos para los eventos keydown y keyup.


Finalmente, todo lo que queda por hacer es llamar una vez al gameloop de nuestro Snake para comenzar el juego. Esto nos da el siguiente código completo para el famoso juego Snake hecho con la API Canvas y la infernal pareja Web HTML5/JavaScript:

Nuestro juego de serpientes en acción

Nuestro Snake completo, es hora de probarlo en un navegador web para ver si la magia del Snake vuelve a funcionar, como lo hizo cuando Nokia dominó escandalosamente el mundo móvil:



A partir de este juego de Snake, puedes imaginar varias mejoras posibles. Por ejemplo, podrías agregar un sonido cada vez que la serpiente se coma la manzana. Puede utilizar la API de almacenamiento web de HTML5 para almacenar la puntuación más alta local de un jugador. De esta forma, cuando un jugador supere su puntuación más alta, podrás mostrar un mensaje de felicitación. Las posibilidades son infinitas y tu único límite, como siempre en la programación, es tu imaginación.


Mira este tutorial en YouTube

Este tutorial también se puede ver en YouTube en el canal SSaurel:


También publicado aquí .