Hace unas semanas, estuve haciendo un curso de android en Coursera. Por hacer este curso, regalaban otro curso en la academia de Zenva: HTML5 Mobile Game Development By Example – Educational Game. Este curso se compone de una serie de videotutoriales hechos por Pablo Farías, fundador de Zenva. En el curso se explica a lo largo de 18 vídeos como crear un juego educativo desde cero utilizando un framework del cual no había oído hablar nunca: Quintus.
Quintus, según lo describen sus creadores, es un motor de juegos Javascript HTML5 sencillo de aprender y divertido de utilizar. Después de haberlo utilizado durante las últimas 3 semanas, estoy muy de acuerdo con esta descripción. Está en una fase muy temprana todavía de desarrollo pero en su estado actual, es posible hacer cosillas bastante interesantes. He decidido escribir esta serie de artículos como un diario mientras hacía este shoot ’em up con Quintus. Ojalá pueda ser de ayuda para otras personas deseosas de aprender a utilizar Quintus.
¿Por dónde empezar?
Cuando empecé el curso de Zenva, uno de los primeros consejos proporcionados por Pablo Farías fue el de adentrarme en el código de Quintus, intentar leerlo, darle una oportunidad durante media o una hora. Quizás este sea uno de los mejores consejos que me han dado últimamente. En más de una ocasión he intentado utilizar otros frameworks, pero nunca había empezado por revisar el código de estos. En el caso de Quintus, el código está muy bien documentado y, aunque es cierto que no llego a entender todo lo que hace, sí que me ha proporcionado una idea más clara de lo que se podía hacer con él. Te animo pues a que le eches un vistazo.
Módulos de Quintus
El motor principal se encuentra en quintus.js. Quintus viene además con una serie de módulos que pueden o no ser incluidos en el juego.
- Sprites: El módulo de Sprites es uno de los módulos más importantes de Quintus. Este módulo es el responsable del tratamiento de los spritesheets de tu juego y también contiene la clase base Sprite que es la que se suele extender para crear nuevos objetos.
- Scenes: El módulo de Scenes es otro de los módulos que más se utilizan. Es el encargado de dar soporte a las Scenes y Stages dentro de Quintus. Este módulo depende directamente del de Sprites. Un Stage es un contenedor de Sprites y métodos. Una Scene es una serie de instrucciones para iniciar un Stage. Por ejemplo, para crear el nivel 1 de mi juego, crearé una Scene llamada “level1” y en el Stage que se iniciará junto con esta Scene, insertaré mis Sprites («player» y «enemy») y arrancaré la música de fondo. También podría crear otra Scene llamada “menu” que sería el menú de inicio con las típicas opciones de Jugar o Créditos, u otra llamada “gameover” que sea la escena final.
- Input y Touch: Estos dos módulos se encargan de capturar y gestionar las interacciones del jugador. El módulo Touch se centra en los controles de dispositivos táctiles y el módulo Input en los controles con ratón, pad o teclado. En el módulo Input, también se encuentran dos componentes platformerControls que añade controles básicos para hacer un juego de plataformas en 2d y stepControls que permite sólo un movimiento por ciclo y devuelve el objeto al origen si se encuentra con algo en su destino.
- Anim: Este módulo permite por un lado definir animaciones para tus sprites y también trae una serie de métodos para poder visualizar esas animaciones. Tendrás que añadir el componente a tu Sprite para poder utilizarlos. También viene con un componente Tween por si no utilizas animaciones con sprites.
- Audio: Se encarga de gestionar el audio de tu juego.
- 2D: Contiene una serie de componentes que permiten crear un juego de plataformas en 2D de forma más sencilla. Trae tres componentes:
- Viewport permite gestionar la cámara.
- TileLayer da soporte a una tile grid.
- 2d activa un comportamiento de físicas por defecto así como la detección de colisiones.
- UI: Define una serie de métodos y elementos que serán útiles para crear la interfaz del juego.
- TMX: Este módulo carga archivos TMX. En mi caso, no lo he utilizado todavía.
Basta de charla, quiero ver algo en pantalla ¡YA!
Si eres igual que yo de impaciente, no habrás tardado en descargarte el repositorio de Quintus y empezar a jugar con él. Es bastante fácil hacer aparecer un sprite y por lo tanto esto anima a continuar aprendiendo. Para empezar, creo una carpeta para mi juego y dentro de la misma cuatro carpetas y un html:
- audio: Contendrá los archivos de sonido.
- data: Contendrá los JSON de los sprites.
- images: Contendrá los sprites.
- js: Contendrá Quintus y los módulos por separado. Para el desarrollo, utilizaré las versiones sin comprimir de los archivos.
- index.html: Donde pondré tanto el html como el js de nuestro juego. Aquí lo tenéis con comentarios.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
<!doctype html> <html> <head> <meta charset="UTF-8"> <title>Cómo hacer un juego shoot ’em up con Quintus</title> <style> /** Un poco de css no hace daño. **/ body { padding: 0; margin: 0; background: #fff; } /** Fondo negro para nuestro canvas. **/ canvas { background: #000; } </style> </head> <body> <!-- Cargando quintus y todos sus módulos por si acaso --> <script src="js/quintus.js"></script> <script src="js/quintus_2d.js"></script> <script src="js/quintus_anim.js"></script> <script src="js/quintus_audio.js"></script> <script src="js/quintus_input.js"></script> <script src="js/quintus_scenes.js"></script> <script src="js/quintus_sprites.js"></script> <script src="js/quintus_tmx.js"></script> <script src="js/quintus_touch.js"></script> <!-- Aquí empieza lo bueno --> <script> /** En cuanto cargue la página... **/ window.addEventListener("load", function() { /** Creo una nueva instancia de Quintus en modo desarrollo. **/ var Q = Quintus({ development: true }) /** Incluyo tres módulos Sprites, Scenes y 2D. Son los únicos que necesitaré por ahora. **/ .include("Sprites, Scenes, 2D") /** Doy a mi área de juego un ancho de 320px y un alto de 480px. **/ .setup({ width: 320, height: 480 }); /** Voy a utilizar el componente 2d sobre los objetos Enemy pero no me interesa utilizar la gravedad normal, quiero poder controlar su movimiento. Para eso, lo que hago es "resetear" la gravedad sobre Y. **/ Q.gravityY = 0; /** En vez de hacer uso de las constantes definidas por Quintus en su módulo de Sprites para gestionar las colisiones, voy a crear mis propias constantes con nombres más descriptivos. **/ var SPRITE_PLAYER = 1; var SPRITE_BULLET = 2; var SPRITE_ENEMY = 3; /** Voy a empezar extendiendo la clase MovingSprite para crear mi clase Player. Esta clase Player será la responsable de manejar el comportamiento y los eventos de la nave jugador. **/ Q.MovingSprite.extend("Player", { init: function(p) { /** Sobreescribo el constructor para poder inicializar mi objeto Player con las propiedades que necesito. Por defecto, mi Player deberá: - utilizar el sprite "player". - ser del tipo SPRITE_PLAYER. - colisionar sólo con objetos del tipo SPRITE_ENEMY. **/ this._super(p, { sheet: "player", sprite: "player", type: SPRITE_PLAYER, collisionMask: SPRITE_ENEMY }); } }); /** Ahora voy a hacer lo mismo para crear mi clase Enemy. Esta clase será responsable de los enemigos. **/ Q.MovingSprite.extend("Enemy", { init: function(p) { /** Sobreescribo el constructor para poder inicializar mi objeto Enemy con las propiedades que necesito. Por defecto, mi Enemy deberá: - utilizar el sprite "enemy". - ser del tipo SPRITE_ENEMY. - colisionar tanto con objetos del tipo SPRITE_BULLET como SPRITE_PLAYER. **/ this._super(p, { sheet: "enemy", sprite: "enemy", type: SPRITE_ENEMY, collisionMask: SPRITE_BULLET | SPRITE_PLAYER }); /** Además añado el componente 2d a este objeto. De esta forma, las colisiones de este objeto con los objetos del colisionMask que he definido funcionarán. De esta manera, también los enemigos se moverán hacia abajo al aplicarles un valor positivo en vY. **/ this.add("2d"); } }); /** Voy a definir una Scene "level1" que será el primer nivel del juego. En esta escena, añadiré los sprites que necesite. **/ Q.scene("level1", function(stage) { /** JUGADOR - Inserto un jugador en el stage. Su posición será el centro del ancho y un poco por encima de la parte de abajo (20px). **/ var player = stage.insert(new Q.Player({ x: Q.width/2, y: Q.height - 20 })); /** ENEMIGOS - Inserto enemigos en el stage. Para eso, calculo un número aleatorio de enemigos que aparecerán a distinta altura y fuera de la visión del canvas, e invisibles al jugador. Esto no es la mejor manera de hacerlo pero por ahora sirve. La propiedad vY sirve para definir la velocidad a la que bajará el enemigo pero sólo referente al eje Y. El enemigo no se moverá sobre el eje X. Por lo tanto, sólo se moverá hacia abajo y no hacia los lados. **/ var num_enemies = Math.floor(Math.random() * 10 + 10); var enemies = new Array(num_enemies); for (var i=0; i <= num_enemies; i++) { enemies.push(stage.insert(new Q.Enemy({ x: (Math.random() * (Q.width-120)) + 120, y: -(Math.random() * 50) - (100*i), vY: Math.random() * 75 + 100 }))); } }); /** En este método, voy a cargar las imágenes y spritesheets necesarios para mi juego. También cargaré el audio en el futuro en este método. Quintus se encarga de buscar los archivos en sus carpetas correspondientes. - En data, buscará los JSON de los sprites. - En audio, buscará los sonidos. - En images, buscará las imágenes. Eres libre de modificar este comportamiento y definir tus propias rutas para que Quintus localice tus archivos, debes hacerlo cuando creas la instancia de Quintus: var Q = Quintus({ imagePath: "http://cdn.yourgame.com/assets/", audioPath: "http://cdn.yourgame.com/assets/", dataPath: "http://cdn.yourgame.com/assets/" }); **/ Q.load("sprites.png, sprites.json", function() { /** He proporcionado a Quintus dos archivos: sprites.png y sprites.json. En sprites.png, están todas las imágenes que necesito para mi juego: - Una bala. - Una nave del jugador y una explosión. - Una nave enemiga y una explosión. En el sprites.json, he definido las posiciones y tamaños de mis sprites. **/ Q.compileSheets("sprites.png", "sprites.json"); /** Esta instrucción arranca un Stage con mi Scene "level1". **/ Q.stageScene("level1"); }); }); </script> </body> </html> |
Con este código, puedes ver el jugador en pantalla, a los enemigos caer con una velocidad endiablada de la parte de arriba y comprobar que el jugador y los enemigos colisionan correctamente. Este código muestra los siguientes conceptos:
- Crear una instancia de Quintus, incluir módulos y configurar un tamaño de canvas.
- Extender la clase MovingSprite para crear nuestros propias clases necesarias para el juego. Aquí he creado la clase “Player” y la clase “Enemy”.
- Sobreescribir el constructor de MovingSprite para añadir propiedades por defecto a mis clases.
- Definir el tipo de un Sprite y la máscara de colisión con el fin de que Quintus y su módulo 2d pueda gestionar las colisiones. En la clase Enemy, he definido una máscara de colisión sobre más de un tipo de objeto.
- Añadir un componente sobre un objeto. He añadido el componente 2d sobre el objeto Enemy para activar las colisiones.
- Crear una Scene añadiendo el jugador y varios enemigos de forma aleatoria.
- Cargar los archivos necesarios para nuestro juego y arrancar un Stage con la Scene definida anteriormente.
- Cargar spritesheets.
Por ahora, esto es todo, en el siguiente artículo mostraré como hacer que se mueva la nave del jugador, cómo hacer que dispare y lo más interesante ¡hacer que los enemigos mueran! al colisionar con las balas.
Este artículo forma parte de una serie:
- ¿Cómo hacer un juego Shoo’Em Up con Quintus? – Parte 1
- ¿Cómo hacer un juego Shoo’Em Up con Quintus? – Parte 2
- ¿Cómo hacer un juego Shoo’Em Up con Quintus? – Parte 3
Las imágenes utilizadas son de SpriteLib.