Saltar al contenido →

Diario Breakout – Parte 4

En esta cuarta parte de Diario Breakout, explicaré como convertir este juego en un juego de verdad. A este juego le falta un menú, botones, un botón de pausa, puntuaciones y sobre todo un «Game Over». ¿Qué es un videojuego sin «Game Over»?

Para poder un poco de orden en todo esto, voy a cambiar el html y crear un archivo de estilos css. En el html, voy a añadir un div que contendrá las puntuaciones y las vidas restantes del jugador y otro div oculto en el que tendré los elementos del menú.

El div de id «menu» contiene los elementos necesarios en nuestro menú:

  • El nombre del juego.
  • El mensaje que se muestra en el «Game Over».
  • El mensaje que se muestra cuando el usuario gana la partida.
  • El mensaje que se muestra cuando el usuario pierde una vida.
  • El botón «Play» que se muestra sólo cuando el usuario pierde la partida («Game Over») o la primera vez que inicia la partida.
  • El botón «Resume» que se muestra sólo cuando el usuario pierde una vida o pausa el juego.
  • El botón «Quit» que se muestra sólo cuando el usuario pausa el juego.

El div de id «scoreboard» contiene los elementos «score» y «lives». En estos dos elementos, almacenaré la puntuación del usuario y las vidas que le quedan. No pondré el contenido del archivo css, como siempre lo tenéis disponible en la demo. Sólo os diré que utilizo la fuente gratuita Freedom para los textos.

Cambios en game.js, creación de la clase Game

He decidido reorganizar por completo el archivo principal del juego «game.js», crear una clase de la misma manera que he venido haciendo con el resto de entidades del juego. En este caso, he decidido utilizar un nuevo patrón: Singleton. El objetivo de este patrón es evitar que se puedan crear más de una instancia de la clase Game. No tiene sentido que exista más de una instancia de esta clase, por lo tanto me pareció el patrón adecuado.

He añadido a esta clase los estados del juego. Un juego pasa por distintos estados y puede programarse en función de ellos. En este breakout, he definido los siguientes estados:

  • GAME_INIT: Estado inicial del juego. Cuando se inicia el juego, este es el estado en el que está.
  • GAME_PLAYING: Estado jugando del juego. Cuando se pulsa en el botón «Play» o en el botón «Resume», el juego pasa a este estado.
  • GAME_OVER: Estado del juego cuando se ha perdido todas las vidas.
  • GAME_WIN: Estado del juego cuando se ha destruído todos los bloques.
  • GAME_LIFELOST: Estado del juego cuando se pierde una vida.
  • GAME_PAUSE: Estado del juego cuando se pulsa la barra espaciadora, se pausa el juego.

He añadido varios métodos y hecho cambios en los que ya tenía:

  • addEvents: Este método añade los eventos click a los botones del menú y el evento al pulsar la barra espaciadora que pausará el juego o reaundará el juego después de pausarlo.
  • gameloop: En este método, he añadido la comprobación del estado del juego para poder saber qué hacer en cada momento. Si está en el estado «GAME_PLAYING», el código es muy parecido a lo que tenía antes. En cualquier otro de los estados, se muestra el menú.
  • showMenu: Este método como su nombre indica se encarga de mostrar el menú. Según el estado en el que está el juego, mostrará unas opciones u otras.
  • hideMenu: Este método oculta el menú por completo.
  • resumeGame: Este método se encarga de reanudar el juego después de una pausa.
  • pauseGame: Este método se encarga de pausar el juego.
  • startGame: Este método se encarga de iniciar una nueva partida, reinicia la puntuación, las vidas restantes y todos los elementos del juego.
  • updateScore: Este método se encarga de actualizar la puntuación del jugador.
  • updateLives: Este método se encarga de actualizar las vidas restantes del jugador.
  • checkCollisions: Este método ha sufrido algún cambio. Al método «checkCollisions» de la clase Ball, le paso ahora la instancia de la clase Game. Esto es necesario ya que ahora existe la posibilidad de perder y necesito llamar a un método (al método «lose») desde la clase Ball. Además si no quedan bloques en el array «bricks», eso significa que el usuario ha ganado.
  • drawAll: Este método ha sufrido cambios. Ahora sólo se dibujan los elementos si existe, de esta forma, podemos llamar a este método sin miedo de que surja algún error por haber reiniciado el juego anterior.
  • lose: Este método es llamado por la clase Ball sólo cuando la bola impacta contra el borde inferior del canvas, esto significa que se nos ha escapado y por lo tanto el jugador pierde una vida. El juego cambia al estado «GAME_LIFELOST». Si el jugador no tiene vidas, se llama al método «gameover» sino se reinicia la posición de la bola, la posición de la pala y se cambia el estado del juego a «GAME_PAUSE». Esto se hace para evitar que el juego vuelva a empezar y sorprenda al jugador…
  • gameover: Este método se encarga de reiniciar todos los elementos del juego y cambiar el estado del juego a «GAME_OVER». Además se mostrará después el típico mensaje de «Game Over».
  • gamewin: Este método hace lo mismo que el anterior pero cambiando el estado del juego a «GAME_WIN». 
  • resetAll: Este método se encarga de reiniciar los elementos del juego y llama al método drawAll() para dibujar el nuevo estado del canvas.

Este es el código completo del javascript con comentarios. Si tenéis alguna duda, dejadme un comentario.

Cambios en la clase Ball

En la clase Ball, también he hecho varios cambios:

  • He almacenado en «initial_data», los valores iniciales (posición, velocidad y ángulo) de la bola para poder utilizarlo en el método «resetPosition».
  • He cambiado el método «checkCollisions». Ahora recibe como parámetro una instancia de la clase Game. Esto permite que cuando la bola impacta con el borde inferior del canvas, llame al método «lose» para perder una vida, reiniciar la bola y pala y pausar el juego.
  • He añadido el método «resetPosition». Este método se encarga de restaurar la bola a sus valores iniciales.

Este es el código completo de la clase Ball:

Cambios en la clase Paddle

He hecho unos cambios muy parecidos a los hechos en la clase Ball:

  • He almacenado en «initial_data», los valores iniciales de la pala (posición y velocidad).
  • Para las teclas de movimiento, utilizo la clase Game en la que he guardado los códigos de estas.
  • El método «resetPosition» se encarga de restaurar los valores iniciales de la pala.

Aquí viene el código de esta clase:

Esto ya se parece más a un juego

Esto ya es un juego. Tengo un menú, un play, un game over, puntuación, un principio y un fin… Ahora lo ideal sería hacer más niveles de juego, meter sonidos, imágenes, «power-up», … Todo lo que hace de un juego algo que te engancha.

Aquí tenéis el enlace de la demostración: VER DEMO

Algunas de las fuentes que he utilizado:

Este artículo forma parte de una serie:
  1. Introducción: Another Breakout game…
  2. Diario Breakout – Parte 1
  3. Diario Breakout – Parte 2
  4. Diario Breakout – Parte 3
  5. Diario Breakout – Parte 4
  6. Diario Breakout – Parte 5 y ¿última?
  7. Diario Breakout – Integrar Clay.io

He subido Breakout a GitHub.

Prueba la versión final.

Share