Phaser es un framework de código abierto HTML5 juego rápido, libre para escritorio y móviles. Phaser 3 es la próxima generación de marco Phaser con muchas características nuevas y mejoradas, estructura totalmente modular y personalizado nuevo procesador de WebGL. En este tutorial vamos a utilizar Phaser 3 para crear sencillo juego de plataformas al estilo de Mario.

Tabla de contenidos

objetivos de aprendizaje

El objetivo de este tutorial es para enseñar cómo construir un juegos de plataformas con Phaser 3. Usted aprenderá a:


  • mapas de uso de la solería de Phaser 3 juego
  • Crear sprites y animaciones
  • Uso Phaser sistema de física 3 juegos electrónicos
  • Crear la lógica básica de un estilo de Mario juego de plataformas

    Tutorial requisitos

    • Nivel intermedio de Habilidades de JavaScript
    • Una especie de editor de código. Yo prefiero usar Netbeans, pero se puede usar lo que quiera
    • servidor Web – se puede trabajar localmente con Apache, utilizar un servidor web remoto o incluso probar algunos Editores de código JavaScript en línea
    • activos Tutorial – se pueden utilizar los que vienen con el código fuente de descarga o hacer su propio

      Activos de derechos de autor

      Los activos utilizados en este tutorial son creados por Kenney Vleugels y se pueden encontrar en www.kenney.nl. Todos los activos utilizados son de dominio público A0 licencia.

      El código fuente

      Puede descargar los archivos de código fuente y de activos tutorial aquí.

      Aprender Phaser 3 con nuestro nuevo mini-Grado

      El desarrollo del juego HTML5 Mini-Grado ya está disponible para pre-pedido en Zenva Academia. Aprender a código y hacer que los juegos impresionantes con JavaScript y Phaser 3!

      Pre-ordenar ahora

      Crea el proyecto

      En Phaser 3 un objeto de configuración se utiliza para configurar la funcionalidad básica de un juego. El objeto de configuración puede tener un montón de opciones, pero por ahora vamos a agregar sólo los más básicos. Anchura y altura definen el tamaño del elemento de tela que se va a crear. La propiedad es de tipo para el ajuste del tipo de renderizador para nuestro juego, lo volveré a Phaser.AUTO. En este caso Phaser 3 tratará de usar WebGL, pero si no puede, por alguna razón, se utilizará lienzo. Puede cambiar esta opción para Phaser.WEBGL o Phaser.CANVAS de procesador correspondiente.
      Ahora vamos a crear proyecto simple Phaser 3 con solamente la escena predeterminada e implementaremos tres funciones:


      • precarga – cargas de los recursos del juego
      • crear – crear el mapa, el jugador y los demás objetos del juego
      • Actualización – Actualiza el juego

        Para nuestro juego de plataformas al estilo de Mario Voy a utilizar la física Phaser 3 arcade. A fin de que desde el principio, es necesario agregar la propiedad física al objeto de configuración:
        la física: {default: ‘Arcade’, Arcade: {gravedad: {Y: 500}, // afectará nuestra depuración de sprites jugador: // falsa cambio si es necesario}}, 1234567physics: {default: ‘Arcade’, arcade: {gravedad: {y: 500}, // afectará nuestra spritedebug jugador: // falsa cambio Si necesita}},

        manera directa muy rápido y realmente añadir sistema de física a un juego. Además, he añadido una propiedad de la gravedad a lo que va a funcionar en el reproductor de nuestro sprite. Así que aquí es nuestro vacío, pero completamente funcional proyecto Phaser 3 con la física de arcade habilitado:
        var config = {type: Phaser.AUTO, anchura: 800, altura: 600, la física: {default: ‘Arcade’, arcade: {gravedad: {y: 500}, de depuración: false}}, escena: {key: ‘ principal, precarga: precarga, crear: crear, actualizar: update}}; juego var = new Phaser.Game (config); var map; var player; cursores var; var groundLayer, coinLayer; var texto; precarga function () { } function crear () {} actualización función () {} 1234567891011121314151617181920212223242526272829303132333435363738varconfig = {tipo: Phaser.AUTO, anchura: 800, altura: 600, la física: {default: ‘Arcade’, arcade: {gravedad: {y: 500}, depuración: false}}, escena: {clave: ‘principal’, precarga: precarga, crear: crear, actualizar: update}}; vargame = newPhaser.Game (config); varmap; varplayer; varcursors; vargroundLayer, coinLayer; vartext; functionpreload () {} functioncreate () {} functionupdate () {}

        Cargar los activos

        Ahora tenemos que cargar los activos en el juego. Phaser 3 viene con funcionalidad de carga agradable, así que sólo tiene que añadir sus activos en la función de precarga y el motor se carga automáticamente nada definido en ella cuando se inicia.
        Aquí es cómo nuestra precarga función debe ser:
        función de precarga () {// mapa hecho con baldosa en formato JSON this.load.tilemapTiledJSON ( ‘mapa’, ‘activos / map.json’); // azulejos en spritesheet this.load.spritesheet ( ‘azulejos’, ‘activos / tiles.png’, {frameWidth: 70, frameHeight: 70}); // sencilla monedas imagen this.load.image ( ‘moneda’, ‘activos / coinGold.png’); // animaciones de los jugadores this.load.atlas ( ‘jugador’ ‘activos / player.png’, ‘Activos / player.json’);} 12345678910functionpreload () {// mapa realizado con baldosa en JSON formatthis.load.tilemapTiledJSON ( ‘mapa’, ‘activos / map.json’); // azulejos en spritesheet this.load.spritesheet ( ‘azulejos’, ‘activos / tiles.png’, {frameWidth: 70, frameHeight: 70}); // sencilla imagethis.load.image moneda ( ‘moneda’, ‘activos / coinGold.png’); // animationsthis.load.atlas jugador ( ‘jugador’, ‘activos / player.png’, ‘activos / player.json’); }

        Esto cargará cuatro activos – nuestro mapa realizado con baldosa Editor, un spritesheet que contiene nuestras baldosas, una imagen de la moneda y el jugador animaciones en una imagen atlas .

        Al ejecutar el juego ahora sólo mostrará la pantalla en negro, ya que no hemos añadido nada a nuestra escena.

        Crea el mundo

        El mapa para este tutorial se crea con baldosa Editor de mapas. Usted puede crear su propio mapa con ella o utilizar el mapa que viene con los archivos de origen para este tutorial. Nuestra mapa tiene dos capas – una para las baldosas del suelo, llamado ‘Mundo’ y uno que contiene las monedas con el nombre ‘monedas’. El mapa debe ser exportado en formato JSON.
        Ahora tenemos que añadir el mapa de la escena. Añadir este código al crear Función:
        // cargar el mapa = this.make.tilemap ({clave: ‘mapa’}); // azulejos para la capa de suelo var groundTiles = map.addTilesetImage ( ‘azulejos’); // crear la capa de suelo groundLayer = map.createDynamicLayer ( ‘Mundo’, groundTiles, 0, 0); // el jugador chocará con esta groundLayer.setCollisionByExclusion capa ([- 1]); // establecer los límites de nuestro mundo del juego this.physics.world.bounds.width = groundLayer.width; this.physics.world.bounds.height = groundLayer.height; 12345678910111213 // cargar el mapa = this.make.tilemap ({clave: ‘mapa’}); // azulejos para los layervargroundTiles tierra = map.addTilesetImage (‘ azulejos ‘); // crear el suelo layergroundLayer = map.createDynamicLayer (‘ Mundo’, groundTiles, 0,0); // el jugador chocará con este layergroundLayer.setCollisionByExclusion ([- 1]); // establecer los límites de nuestro juego worldthis.physics.world.bounds.width = groundLayer.width; this.physics.world.bounds.height = groundLayer.height;

        necesitará las dos últimas filas para limitar el movimiento de nuestro jugador y la cámara mas tarde. No queremos perder el jugador de sprites fuera de la pantalla del juego así que hacemos el mundo limitado al tamaño de la capa.

        Bien, ahora tenemos nuestro mundo de juegos listos. Aquí hay una captura de pantalla de cómo debe mirar:

        Añadir el reproductor

        Es hora de añadir el reproductor de sprites. Agregue el código de abajo en la parte inferior de la crear Función:
        // crear el jugador jugador de sprites = this.physics.add.sprite (200, 200, ‘jugador’); player.setBounce (0,2); // nuestro jugador va a rebotar de artículos player.setCollideWorldBounds (true); // no salen de la map1234 // crear el Reproductor de sprites = this.physics.add.sprite (200.200, ‘jugador’); player.setBounce (0,2); // nuestro jugador va a rebotar de itemsplayer.setCollideWorldBounds (true); // no salen del mapa

        Usted verá que no sólo estamos creando un sprite, sino que utiliza el objeto física del juego de fábrica para que nuestro jugador por lo que tiene el cuerpo física dinámica añadida a ella desde el comienzo. A continuación, establecemos una propiedad de rebote a ella y hacer que el jugador chocan con los límites de la física del mundo.

        Cuando se protege el juego en su navegador se encuentra que tenemos un problema. Nuestro jugador no se quedan en el suelo, pero cae a través de él a la parte inferior del juego. La solución de este problema es añadir colisión con la capa de suelo. Así es como se hace en el estilo Phaser 3 – añadir este código al final de la crear Función:
        this.physics.add.collider (groundLayer, reproductor); 1this.physics.add.collider (groundLayer, reproductor);

        En Phaser 2 le añada su cheque de colisiones durante la actualización, pero Phaser 3 hace que sea automáticamente con el Colisionador objeto.
        Ahora tenemos el jugador chocan con las plataformas y tenemos que hacer que se mueva cuando se pulsa una tecla. Para este juego vamos a utilizar las teclas de flecha del teclado. Phaser tiene una acumulación en el gestor de teclado y es una opción buena para nuestro juego de plataformas.
        Agregue el código abajo al final de la función de crear:
        cursores = this.input.keyboard.createCursorKeys (); 1cursors = this.input.keyboard.createCursorKeys ();

        Ahora el objeto cursores se rellena con cuatro objetos principales: izquierda, derecha, arriba y abajo. Aquí es cómo podemos utilizarlos para comprobar si se pulsa una tecla en nuestra función de actualización:
        si (cursors.left.isDown) // si la tecla de flecha izquierda está abajo {player.body.setVelocityX (-200); // movimiento izquierda} else if (cursors.right.isDown) // si la tecla de flecha derecha abajo {player.body.setVelocityX (200); // movimiento correcto} if ((cursors.space.isDown || cursors.up.isDown) && player.body.onFloor ()) {player.body.setVelocityY (-500); // saltar} 123456789101112if (cursors.left.isDown) // si la tecla de flecha izquierda está abajo {player.body.setVelocityX (-200); // movimiento izquierda} elseif (cursors.right.isDown) // si el tecla de flecha derecha se ha reducido {player.body.setVelocityX (200); // movimiento correcto} if ((cursors.space.isDown || cursors.up.isDown) && player.body.onFloor ()) {player.body. setVelocityY (-500); // saltar}

        Si la tecla izquierda se ha reducido conjunto nos reproductor de velocidad a un valor negativo y el jugador se mueve a la izquierda. Si la tecla de flecha derecha abajo nos fijamos el reproductor de velocidad a un valor positivo y el movimiento correcto. Si no hay ningún botón Izquierda o Derecha es sostener el jugador no se mueve horizontalmente.
        Si la tecla de flecha hacia arriba es retenida y el cuerpo del jugador está en contacto con el suelo, lo hacemos saltar. Esto se logra mediante el establecimiento de la velocidad y a un número negativo. Usted puede experimentar con esto y la gravedad para obtener una mejor comprensión de los movimientos de los jugadores.

        Como se puede comprobar ahora el jugador puede mover sprites y saltar, pero las estancias de la cámara inmóvil. Haciendo la cámara sigue el jugador es muy sencillo, sólo tiene que llamar al método startFollow cámara. También vamos a querer parar la cámara salga del mundo del juego por lo que vamos a utilizar sus setBounds limitarlo al tamaño del mapa. Agregue el código siguiente a la sección crear Función:
        // establecer límites para que la cámara no va a salir de los this.cameras.main.setBounds mundo de juego (0, 0, map.widthInPixels, map.heightInPixels); // hacer que la cámara siga al jugador this.cameras.main.startFollow (reproductor); // set color de fondo, por lo que el cielo no es this.cameras.main.setBackgroundColor negro ( ‘# ccccff’); 1234567 // límites establecidos para que la cámara no va a salir de los worldthis.cameras.main.setBounds juego (0,0, map.widthInPixels, map.heightInPixels); // hacer que la cámara siga el playerthis.cameras.main.startFollow (reproductor); // set color de fondo, por lo que el cielo no es this.cameras.main.setBackgroundColor negro ( ‘# ccccff’);

        Ahora tenemos otro problema – jugador nuestros mueve a la izquierda y la derecha y saltos, pero hay hay animación paseo.
        Su tiempo de mencionar que el ‘jugador’ se carga como atlas de textura, que es una combinación de imágenes en una imagen grande. En nuestro caso el jugador atlas contiene caminar y estar parado marcos de nuestro personaje del jugador. Su no está en el alcance de este tutorial para explicar los atlas de textura en detalles, pero si usted no está familiarizado con el término, recomiendo que usted investigue más en ello ahora.
        Para la animación a pie del Atlas contiene los fotogramas ‘p1_walk01.png’, ‘p1_walk02.png’ … a ‘p1_walk11.png’. Para hacer la animación simple paseo a partir de estos marcos es necesario definir de esta manera:
        this.anims.create ({clave: ‘caminar’, marcos: this.anims.generateFrameNames ( ‘jugador’, {prefijo: ‘p1_walk’, empezar: 1, final: 11, zeroPad: 2}), frameRate: 10, repetir: -1}); 123456this.anims.create ({clave: ‘caminar’, marcos: this.anims.generateFrameNames ( ‘jugador’, {prefijo: ‘p1_walk’, empezar: 1, final: 11, zeroPad: 2 }), frameRate: 10, de repetición: -1});

        primero la propiedad clave es el nombre de esta animación. A continuación tenemos que añadir los marcos para que, en nuestro caso usamos las generateFrameNames función para añadir todos los marcos de caminar fácilmente. La propiedad conjunto de repetición a -1 dice Phaser al bucle de esta animación. La propiedad frecuencia de imagen es bastante explicativo.

        No utilizaré dos animaciones separadas para el movimiento a izquierda y derecha, en vez voy a utilizar sólo una animación de ‘caminar’ y voy a darle la vuelta al jugador. De volteo se realiza con la propiedad player.flipX. Así es como el actualización función debe mirar ahora:
        actualización de la función (tiempo, delta) {if (cursors.left.isDown) {player.body.setVelocityX (-200); // mover player.anims.play izquierda ( ‘paseo’, true); // juego paseo animación player.flipX = true; // voltear el sprite a la izquierda} else if (cursors.right.isDown) {player.body.setVelocityX (200); // mover player.anims.play derecha ( ‘paseo’, true); // juego paseo Animatio player.flipX = false; // utilizar el sprite original, mirando hacia la derecha} else {player.body.setVelocityX (0); player.anims.play ( ‘inactivo’, true); }} 1234567891011121314151617functionupdate (tiempo, delta) {if (cursors.left.isDown) {player.body.setVelocityX (-200); // movimiento leftplayer.anims.play ( ‘paseo’, true); // juego paseo animationplayer. flipX = true; // voltear el sprite a la izquierda} elseif (cursors.right.isDown) {player.body.setVelocityX (200); // movimiento rightplayer.anims.play ( ‘paseo’, true); // juego caminar animatioplayer.flipX = false; // utilizar el sprite original, mirando hacia la derecha} else {player.body.setVelocityX (0); player.anims.play ( ‘inactivo’, true);}}

        Es hora de añadir algo para recoger – las monedas. Vamos a añadir otra capa Azulejos dinámica a nuestro mundo de juego:
        // imagen de la moneda se utiliza como conjunto de baldosas var coinTiles = map.addTilesetImage ( ‘moneda’); // añadir monedas como azulejos coinLayer = map.createDynamicLayer ( ‘monedas’, coinTiles, 0, 0); 1234 imagen // moneda utilizada como tilesetvarcoinTiles = map.addTilesetImage ( ‘moneda’); // añadir monedas como tilescoinLayer = map. createDynamicLayer ( ‘monedas’, coinTiles, 0,0);

        Ahora las monedas son visibles, pero tenemos que ser capaces de recogerlos. Añadir este código al crear Función:
        coinLayer.setTileIndexCallback (17, collectCoin, este); // el ID de moneda es 17 // cuando el jugador solapamientos con un azulejo con el índice 17, collectCoin serán llamados this.physics.add.overlap (jugador, coinLayer); 123coinLayer.setTileIndexCallback (17, collectCoin, este); // el ID de moneda es 17 // cuando el jugador solapamientos con un azulejo con el índice 17, collectCoin serán llamados this.physics.add.overlap (jugador, coinLayer);

        el setTileIndexCallback función se puede utilizar para invocar ciertas acciones cuando el jugador toca algunos azulejos.

        Esto es lo que su crear función debe ser:
        función de crear () {// cargar el mapa = this.make.tilemap ({clave: ‘mapa’}); // azulejos para la capa de suelo var groundTiles = map.addTilesetImage ( ‘azulejos’); // crear la capa de suelo groundLayer = map.createDynamicLayer ( ‘Mundo’, groundTiles, 0, 0); // el jugador chocará con esta groundLayer.setCollisionByExclusion capa ([- 1]); // imagen de la moneda se utiliza como conjunto de baldosas var coinTiles = map.addTilesetImage ( ‘moneda’); // monedas Agregar como azulejos coinLayer = map.createDynamicLayer ( ‘monedas’, coinTiles, 0, 0); // establecer los límites de nuestro mundo del juego this.physics.world.bounds.width = groundLayer.width; this.physics.world.bounds.height = groundLayer.height; // crear el jugador jugador de sprites = this.physics.add.sprite (200, 200, ‘jugador’); player.setBounce (0,2); // nuestro jugador va a rebotar de artículos player.setCollideWorldBounds (true); // no salen del mapa // pequeño arreglo a nuestras imágenes de los jugadores, que cambia el tamaño del objeto cuerpo ligeramente la física player.body.setSize (player.width, player.height-8); // jugador colisionará con el nivel de azulejos this.physics.add.collider (groundLayer, reproductor); coinLayer.setTileIndexCallback (17, collectCoin, este); // cuando el jugador solapamientos con un azulejo con el índice 17, collectCoin // serán llamados this.physics.add.overlap (jugador, coinLayer); // animación jugador paseo this.anims.create ({clave: ‘caminar’, marcos: this.anims.generateFrameNames ( ‘jugador’, {prefijo: ‘p1_walk’, empezar: 1, final: 11, zeroPad: 2}) , frameRate: 10, de repetición: -1}); // inactivo con una sola trama, por lo que la repetición no se neaded this.anims.create ({clave: ‘inactivo’, marcos: [{clave: ‘jugador’, marco: ‘p1_stand’}], frameRate: 10,}) ; cursores = this.input.keyboard.createCursorKeys (); // establecer límites para que la cámara no va a salir de los this.cameras.main.setBounds mundo de juego (0, 0, map.widthInPixels, map.heightInPixels); // hacer que la cámara siga al jugador this.cameras.main.startFollow (reproductor); // set color de fondo, por lo que el cielo no es this.cameras.main.setBackgroundColor negro ( ‘# ccccff’);} 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061functioncreate () {// cargar el mapa = this.make.tilemap ({clave: ‘mapa’ }); // azulejos para los layervargroundTiles tierra = map.addTilesetImage ( ‘baldosas’); // crear el suelo layergroundLayer = map.createDynamicLayer ( ‘Mundo’, groundTiles, 0,0); // el jugador chocará con esta layergroundLayer.setCollisionByExclusion ([- 1]); // imagen moneda utilizado como tilesetvarcoinTiles = map.addTilesetImage ( ‘moneda’); // añadir monedas como tilescoinLayer = map.createDynamicLayer ( ‘monedas’, coinTiles, 0,0); / / establecer los límites de nuestro juego worldthis.physics.world.bounds.width = groundLayer.width; this.physics.world.bounds.height = groundLayer.height; // crear el sprite del jugador jugador = this.physics.add.sprite (200.200, ‘jugador’); player.setBounce (0,2); // nuestro jugador va a rebotar de itemsplayer.setCollideWorldBounds (true); // no salir de t ES Mapa // pequeño arreglo a nuestras imágenes de los jugadores, que cambia el tamaño del objeto cuerpo física slightlyplayer.body.setSize (player.width, player.height-8); // jugador chocará con el nivel de baldosas this.physics.add.collider (groundLayer, al jugador); coinLayer.setTileIndexCallback (17, collectCoin, este); // cuando el jugador solapamientos con un azulejo con el índice 17, collectCoin // serán llamados this.physics.add.overlap (jugador, coinLayer); / / reproductor paseo animationthis.anims.create ({clave: ‘caminar’, marcos: this.anims.generateFrameNames ( ‘jugador’, {prefijo: ‘p1_walk’, empezar: 1, final: 11, zeroPad: 2}), frameRate : 10, de repetición: -1}); // inactivo con una sola trama, por lo que la repetición no es neadedthis.anims.create (tecla {: ‘inactivo’, marcos: [{clave: ‘jugador’, marco: ‘p1_stand’ }], frameRate: 10,}); cursores = this.input.keyboard.createCursorKeys (); // establecer límites para que la cámara no va a salir de la worldthis.cameras.main.setBounds juego (0,0, mapa. widthInPixels, map.heightInPixels); // hacer que la cámara siga el playerthis.cameras.main.startFollow (reproductor); // set color de fondo, por lo que el cielo i No es this.cameras.main.setBackgroundColor negro ( ‘# ccccff’);}

        Ahora tenemos que poner en práctica la , función collectCoin. En ella vamos a eliminar el mosaico que representa la moneda tocado. Aquí está el código para ello:
        función collectCoin (sprite, baldosas) {coinLayer.removeTileAt (tile.x, tile.y); // eliminar el falso retorno del azulejo / de la moneda;} 1234functioncollectCoin (sprite, baldosas) {coinLayer.removeTileAt (tile.x, tile.y); // eliminar el azulejo / coinreturnfalse; variable de puntuación add}

        Lets y un texto para mostrar la cantidad de monedas que hemos recogido.
        Añadir este en la parte superior del juego cerca de las otras variables:
        var texto;; puntuación var = 0

        Y esto al final de la crear Función:
        text = this.add.text (20, 570, ‘0’, {fontSize: ’20px’, relleno: ‘#ffffff’}); text.setScrollFactor (0); 12345text = this.add.text (20570, ‘0’, {fontSize: ’20px’, relleno: ‘# FFFFFF’}); text.setScrollFactor (0);

        Aquí creamos un objeto de texto de juegos con tamaño de fuente de 20 y de color blanco. Hemos establecido su factor de desplazamiento a 0; esto le dice Phaser para fijarlo a la pantalla. Ahora bien, cuando se recoge una moneda que podemos incrementar la puntuación y establecer el texto para indicar que:
        función collectCoin (sprite, baldosas) {coinLayer.removeTileAt (tile.x, tile.y); // eliminar la puntuación de azulejos / de la moneda ++; // incrementar el text.setText puntuación (score); // establecer el texto para mostrar la corriente de retorno falsa puntuación;} 123456functioncollectCoin (sprite, baldosas) {coinLayer.removeTileAt (tile.x, tile.y); // quitar el azulejo / coinscore ++; // incrementar el scoretext.setText ( marcar); // establecer el texto para mostrar el scorereturnfalse actual;}

        con este nuestro juego de plataformas muy simple está listo. A partir de aquí su hasta usted para desarrollar más y explorar las posibilidades.

        Conclusiones

        En este tutorial aprendió los fundamentos de crear un juego de plataformas al estilo de Mario, como la creación del mundo a partir de un mapa, añadiendo sprites con la física, el control de la interacción entre los objetos físicos. Hay mucho más que se puede hacer, por ejemplo añadiendo un fondo paralaje, creando un nivel más grande, añadiendo más tipos de colección y algunos enemigos. Con la experiencia de este artículo ahora se puede tratar de desarrollar su propio juego de plataformas y ampliar un poco con algunas de las funciones anteriores.

        Mensajes relacionados
        Phaser 3 juego con los barcos azules y rojas duelo Phaser 3, infinito rollo, avión juego de vuelo  3 Phaser dragón juego de cruce tutorial ejemplo

Deja una respuesta

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