Saca tu paleta de colores… o hazte un juego, ¡bienvenidos al canvas!

Ante todo… ¡FELIZ 2024! Espero que este año te traiga todo lo que deseas, y que la programación te haga feliz como nada en el mundo. Ya me irás contando cómo va la cosa, mientras tanto, volvamos a picar un poquito…

Tengo que reconocer que nunca me ha tocado trastear con el canvas en mi vida profesional, esa etiqueta html en plan “caja negra” que detiene al inspector de Chrome en cuanto intenta asomarse. Pero el otro día, viendo un vídeo de @midudev, me picó bastante la curiosidad. Os dejo el vídeo donde comprobaréis, además de lo bueno que es este tío, el potencial del canvas:

Así que pensé “¿por qué no hacemos una serie de post y creamos un jueguecillo?”. Cierto es que en su día trabajé con Flash (viejunner), y que, entre otras cosas, programé algún juego. Ya os enseñaré algo por aquí (cuando acabemos este, podemos poner los sprites del otro 🙂 ).

Vamos a construir una versión muy básica de un juego de naves, el típico con scroll horizontal, disparos, enemigos… Usaremos sprites y cositas de R-Type, un clásico en el género.

En esta primera parte, crearemos la nave con sus movimientos (teclas del cursor) y su disparo (barra espaciadora). Crearemos un botón de START para empezar a jugar (y reproducir el sonido de fondo del juego) y crearemos el espacio para la futura barra de vidas y puntuación.

Aquí tenéis el repo con estas funcionalidades iniciales:

https://github.com/entorno5/canvas-game/

Primero, veamos el aspecto del index.htm; como podéis ver, he metido css y js en el mismo html, para tenerlo todo junto. Antes de detallar un poquito el js (la parte de estilos tampoco merece mucha explicación), quiero que veáis como se pinta el canvas:

  <div id="info">
    <h1>R-TYPE</h1>
    <div id="start-container">
      <button id="startButton">START</button>
    </div>
    <canvas id="miCanvas"></canvas>
    <div id="puntuacion-container">
      Vidas: <span id="vidas">3</span> - Puntuación: <span id="puntuacion">0</span>
    </div>
  </div>

Ahí lo tenéis, limpio, autosuficiente, sin nada en su interior. De hecho, una vez abierto el archivo y con la navecita en juego, si inspeccionais el código veréis que el canvas es una caja negra, no veréis nada dentro de él. Todo se le agrega programáticamente (lo cual os va a complicar debuggear).

Aquí se inicializa el canvas:

    const canvas = document.getElementById('miCanvas');
    const ctx = canvas.getContext('2d');
    canvas.width = 800; // Tamaño fijo en píxeles
    canvas.height = 600; // Tamaño fijo en píxeles
    ctx.scale(1, 1);

Antes hemos creado el sonido para reproducirlo cuando pulsemos START, llamando a la función startGame:

    function startGame() {
      // Asociar el evento de teclado
      window.addEventListener('keydown', manejarTeclado);
      startContainer.style.display = 'none';
      canvasContainer.style.display = 'flex';
      sound.volume = 0.1; 
      sound.play();
      update();
    }

En esta función, antes de reproducir el sonido, añadimos el listener para gestionar los movimientos al pulsar las teclas y ocultamos y mostramos las capas necesarias para quitar el botón de START y mostrar la pantalla de juego.

En el resto de funciones, dibujamos la nave, las balas, y la información del juego. Podrás comprobar que en todos los casos, cuando se va a trabajar con el canvas, se hace referencia a él según lo creamos (ctx en esta caso). Echa un vistazo para que veas lo que hace en cada caso.

Por no entrar en más detalles, veamos dónde está la magia de todo esto:

    function update() {
      draw();
      requestAnimationFrame(update);
    }

    // Iniciar el bucle del juego
    update();

La función update es parte del bucle principal del juego, se encarga de redibujar continuamente la escena del juego en el canvas. Llamando a draw(), se limita la posición de la nave, se mueven las balas, se filtran las balas que están fuera de la pantalla y se llama a las funciones que dibujan los elementos.

La línea con requestAnimationFrame, se encarga de programar la próxima ejecución de la función update antes de que se repinte el siguiente cuadro de animación. Esto crea un bucle continuo que permite la animación fluida del juego.

En 3 o 4 posts más parecerá algo…

Pruébalo. Ya tienes a la nave del R-Type moviéndose por la pantalla, disparando y con su musiquita de fondo. ¿Quieres más funcionalidades? Pues te espero en la siguiente entrega 😉

¡Hasta la semana que viene!

Entradas relacionadas

Deja una respuesta

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