En esta serie de tutoriales va a hacer un juego de rol por turnos similar a los primeros juegos de Final Fantasy, toda vez que aprenden a utilizar muchos de los fresco, nuevas características incorporadas en la versión actual del motor de juego Phaser 3. Para la primera parte de este tutorial vamos a centrar nuestra atención en la creación del mundo, añadiendo el jugador y en movimiento en el mapa. A continuación, vamos a añadir algunas zonas invisibles donde el jugador se reunirá con los malos.
La segunda parte de esta serie le ayudará a aprender cómo crear el sistema de batalla y la interfaz de usuario. Haremos nuestras unidades de luchar contra los enemigos!

Tabla de contenidos

objetivos de aprendizaje

Escenas, manejo de la escena y la interacción, eventos

En este tutorial vamos a aprender cómo crear y utilizar varias escenas y cómo cambiar entre ellos. Vamos a tener una escena para el mapa del mundo y otra para la batalla. En realidad, vamos a tener dos escenas que funcionan al mismo tiempo durante una pelea -. Batalla de la escena y la escena de la interfaz de usuario, donde se verá las estadísticas de héroes, la información y el daño enemigo se mueve

sprites y animaciones

Vamos a tener nuestro sprite de héroe en el mapa del mundo y que utilizará varias animaciones para moverse en diferentes direcciones.

Usar mapa

Usted aprenderá cómo utilizar un mapa de baldosas de motor de juego Phaser 3. Para este tutorial, puede crear su propio mapa de baldosa o utilizar el que viene con las fuentes. Usted aprenderá cómo crear capas del mapa y hacer que el jugador chocan con elementos de la capa mapa.

Arcade Física

Vamos a utilizar la física de arcade para mover el personaje del jugador en el mapa del mundo y para manejar algunas colisiones. Usted aprenderá cómo utilizar grupos Arcade Física, colisionadores y Phaser 3 zonas.

Efectos y cámara

Se va a aprender a utilizar algunos efectos espectaculares, como el temblor y se desvanecen cuando el personaje se encuentra con enemigos y antes de que se inicie una batalla.

Tutorial requisitos

  • Nivel intermedio de JavaScript
  • Editor de código
  • navegador Web
  • servidor web local
  • Activos – mapa en formato JSON y las imágenes (puede usar los que vienen con este archivos del tutorial)

    Activos de derechos de autor

    Todos los activos utilizados en este tutorial son A0 licencia. Los azulejos son creados por Kenney Vleugels y se pueden encontrar en www.kenney.nl
    Los sprites jugador se pueden encontrar aquí – https://opengameart.org/content/rpg-character-sprites

    El código fuente

    Puede descargar el código fuente tutorial aquí.

    No se pierda! extremos de la oferta en

    • Accede a los más de 200 cursos
    • Nuevos cursos añadió mensual
    • Cancelar en cualquier momento
    • Los certificados de terminación

      ACCESO ahora

      Crea el juego

      Vamos a empezar con la creación de un simple juego de Phaser 3 con la ayuda del objeto de configuración. Por ahora, en nuestro juego vamos a comenzar con dos escenas – Escena de arranque y la escena del mundo. Escenas en Phaser 3 son gestionados por el Director de Escena y como veremos en la siguiente parte de este tutorial se puede tener más de una escena activa a la vez.
      Ahora vamos a empezar con algo más fácil -. Creación del juego y cargar los recursos

      Aquí es cómo su proyecto vacío y el objeto de configuración deben buscar:
      var BootScene = nuevo Phaser.Class ({Extiende: Phaser.Scene, initialize: función BootScene () {Phaser.Scene.call (esto, {key: ‘BootScene’});}, precarga: function () {// carga los recursos aquí}, crean: function () {this.scene.start ( ‘WorldScene’);}}); var = new WorldScene Phaser.Class ({Extiende: Phaser.Scene, initialize: WorldScene función () {Phaser. Scene.call (esto, {clave: ‘WorldScene’});}, precarga: function () {}, crear: function () {// crear su mundo aquí}}); var config = {type: Phaser.AUTO , padre: ‘contenido’, anchura: 320, altura: 240, del mapa: 2, pIXELART: true, la física: {default: ‘Arcade’, arcade: {gravedad: {Y: 0}}}, escena: [BootScene, WorldScene]}; var = nuevo juego Phaser.Game (config); 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061varBootScene = newPhaser.Class ({Extiende: Phaser.Scene, initialize: functionBootScene () {Phaser.Scene.call (esto, {clave: ‘BootScene’}) ;}, precarga: function () {// cargar los recursos aquí} , Crear: function () {this.scene.start ( ‘WorldScene’);}}); varWorldScene = newPhaser.Class ({Extiende: Phaser.Scene, initialize: functionWorldScene () {Phaser.Scene.call (esto, { clave: ‘WorldScene’});}, precarga: function () {}, crear: function () {// crear su mundo aquí}}); varconfig = {type: Phaser.AUTO, padre: ‘contenido’, ancho : 320, altura: 240, del mapa: 2, pixelArt: true, la física: {default: ‘Arcade’, arcade: {gravedad: {y: 0}}}, escena: [BootScene, WorldScene]}; vargame = newPhaser. juego (config);

      puede prestar especial atención a la pIXELART: verdadera opción; cuando se define como true, al evitar el desenfoque de las texturas cuando se escala. Lo vamos a utilizar junto con la opción de zoom para hacer la escala juego. En el objeto de configuración le pediremos Phaser para incluir la física de arcade por defecto. Esto nos ayudará a mover nuestro personaje.
      Al final de ella tenemos la opción de escena con todas las escenas de la lista. En el momento actual las dos escenas casi el mismo aspecto. La única deferencia está en el método de la BootScene, donde empezamos la WorldScene con esta fila crear:
      this.scene.start ( ‘WorldScene’); 1this.scene.start ( ‘WorldScene’);

      Cargar los activos

      Cargando activos en Phaser 3 es muy fácil, sólo tiene que añadir lo activos que necesita para el cargador. Añadir este código a la función de precarga del BootScene:
      // Mapa azulejos this.load.image ( ‘azulejos’, ‘activos / mapa / spritesheet.png’); // mapa en formato JSON this.load.tilemapTiledJSON ( ‘mapa’, ‘activos / mapa / map.json’); // nuestros dos personajes this.load.spritesheet ( ‘jugador’ ‘activos / RPG_assets.png’, {frameWidth: 16, frameHeight: 16}); // 12345678 mapa tilesthis.load.image ( ‘azulejos’, ‘Activos /map/spritesheet.png’);// mapa en JSON formatthis.load.tilemapTiledJSON ( ‘mapa’, ‘activos / mapa / map.json’); // nuestros dos charactersthis.load.spritesheet ( ‘El jugador’,’ activos / RPG_assets.png’, {frameWidth: 16, frameHeight: 16});

      Ahora vamos a crear nuestra escena mundo con el mapa que hemos cargado. Esto sucederá en el método de la WorldScene crear:
      var map = this.make.tilemap ({clave: ‘mapa’}); 1varmap = this.make.tilemap ({clave: ‘mapa’});

      El parámetro clave es el nombre, nos dio a nuestro mapa cuando se utilizó la this.load.tilemapTiledJSON para cargarlo.
      Ahora, cuando actualice el juego sigue siendo negro. Para tener el mapa en el juego, tenemos que cargar las capas del mapa.

      El mapa para este ejemplo se crea con baldosa Editor. Para seguir el tutorial se puede utilizar el mapa que viene con los archivos de origen o crear su propio mapa. Tengo mapa sencillo preparado con sólo dos capas – la primera se llama ‘hierba’ y contiene mosaicos hierba sólo, el segundo es ‘obstáculos’ y hay algunos árboles en su centro. Así es como se añadirlos en juego.

      Añadir este código al final de WorldScene crear:
      var azulejos = map.addTilesetImage ( ‘spritesheet’, ‘azulejos’); var hierba = map.createStaticLayer ( ‘Grass’, azulejos, 0, 0); obstáculos var = map.createStaticLayer ( ‘obstáculos’, azulejos, 0, 0); obstacles.setCollisionByExclusion ([- 1]); 12345vartiles = map.addTilesetImage ( ‘spritesheet’, ‘azulejos’); vargrass = map.createStaticLayer ( ‘Grass’, azulejos, 0,0); varobstacles = map.createStaticLayer ( ‘Obstáculos ‘, azulejos, 0,0); obstacles.setCollisionByExclusion ([- 1]);

      La primera fila crea una imagen de conjunto de baldosas. Las siguientes dos filas suman las capas al mapa. El último es lo que es interesante. El setCollisionByExclusion método hace que todas las fichas excepto las que mandan, disponible para la detección de colisiones. El envío de -1 en nuestro caso hace que todos los azulejos en este Collidable capa.
      Al abrir el juego en su navegador, usted debe tener algo como esto:

      Su momento de añadir nuestra sprites jugador. Añadir este código al final del método de crear WorldScene:
      this.player = this.physics.add.sprite (50, 100, ‘player’, 6); 1this.player = this.physics.add.sprite (50100, ‘jugador’, 6);

      El primer parámetro es la coordenada x, la segunda es y, la tercera es el recurso de imagen y el último es su marco.
      Para moverse en nuestro mundo Mapa vamos a utilizar la física Phaser 3 Arcade. Para que el jugador a chocar con los obstáculos en el mapa vamos a crear a través del sistema de física -. This.physics.add.sprite

      Añadir tres filas más:
      this.physics.world.bounds.width = map.widthInPixels; this.physics.world.bounds.height = map.heightInPixels; this.player.setCollideWorldBounds (true); 123this.physics.world.bounds.width = map.widthInPixels; this.physics.world.bounds.height = map.heightInPixels; this.player.setCollideWorldBounds (true);

      Esta hará que la estancia jugador dentro de las fronteras del mapa. En primer lugar nos fijamos los límites del mundo, entonces hacemos collideWorldBounds propiedad del personaje en true.

      Mover en el mapa

      Es hora de hacer el movimiento reproductor de sprites en el mapa. Que necesitamos para procesar la entrada del usuario. Para este juego vamos a utilizar las teclas de flecha.

      Añadir este código al final del método de crear:
      this.cursors = this.input.keyboard.createCursorKeys (); 1this.cursors = this.input.keyboard.createCursorKeys ();

      Para mover el reproductor vamos a utilizar el motor de física. Vamos a establecer la velocidad del cuerpo del sprite de acuerdo con la dirección que desea mover. Ahora tenemos que añadir un método de actualización de la WorldScene. Vamos a añadir lógica de movimiento del jugador allí.

      Aquí es cómo su método de actualización debe ser:
      cambio: la función (tiempo, delta) {this.player.body.setVelocity (0); // movimiento Horizontal si (this.cursors.left.isDown) {this.player.body.setVelocityX (-80); } Else if (this.cursors.right.isDown) {this.player.body.setVelocityX (80); } // Vertical movimiento si (this.cursors.up.isDown) {this.player.body.setVelocityY (-80); } Else if (this.cursors.down.isDown) {this.player.body.setVelocityY (80); }} 123456789101112131415161718192021222324update: function (tiempo, delta) {this.player.body.setVelocity (0); // movementif Horizontal (this.cursors.left.isDown) {this.player.body.setVelocityX (-80);} elseif (this.cursors.right.isDown) {this.player.body.setVelocityX (80);} // movementif Vertical (this.cursors.up.isDown) {this.player.body.setVelocityY (-80);} elseif (this.cursors.down.isDown) {this.player.body.setVelocityY (80);}}

      primero fijamos la velocidad cuerpo a 0. Entonces, si una llave apropiada está abajo, fijamos la velocidad en x o de y. Puede probar el movimiento del personaje en su navegador.
      Nuestro jugador puede mover, pero la cámara no seguir. Para hacer que la cámara siga un sprite tenemos que llamar a su método startFollow.

      Añadir este código al final del método de crear WorldScene:
      this.cameras.main.setBounds (0, 0, map.widthInPixels, map.heightInPixels); this.cameras.main.startFollow (this.player); this.cameras.main.roundPixels = true; 123this.cameras.main.setBounds (0,0, map.widthInPixels, map.heightInPixels); this.cameras.main.startFollow (this.player); this.cameras.main. roundPixels = true;

      la primera fila limita la cámara de mantenerse dentro de los límites de mapas. El segundo hace que la cámara siga al jugador.
      La tercera fila this.cameras.main.roundPixels = true; es un poco de un truco para prevenir el sangrado azulejos -. mostrando las líneas de borde en los azulejos

      Una vez más, probar el juego en el navegador. Como se puede ver, los movimientos del jugador se ven muy aburrido, ya que no hay animación paseo. Por lo que necesitamos para animar al personaje. Las animaciones en Phaser3 se realizan a través del Administrador de animaciones. Aquí es cómo vamos a agregar animaciones a nuestro personaje del jugador.

      Para definir las animaciones añadir este código para crear el método de la WorldScene:
      // animación con la tecla ‘izquierda’, no necesitamos a la izquierda y la derecha como vamos a utilizar uno y darle la vuelta al this.anims.create Sprite ({clave: ‘izquierda’, marcos: this.anims.generateFrameNumbers ( ‘jugador’ , {marcos: [1, 7, 1, 13]}), frameRate: 10, de repetición: -1}); // animación con la tecla ‘derecha’ this.anims.create ({clave: ‘derecho’, marcos: this.anims.generateFrameNumbers ( ‘jugador’, {marcos: [1, 7, 1, 13]}), frameRate: 10, repetición: -1}); this.anims.create ({clave: ‘arriba’, marcos: this.anims.generateFrameNumbers ( ‘jugador’, {marcos: [2, 8, 2, 14]}), frameRate: 10, de repetición: -1}) ; this.anims.create ({clave: ‘abajo’, marcos: this.anims.generateFrameNumbers ( ‘jugador’, {marcos: [0, 6, 0, 12]}), frameRate: 10, de repetición: -1}) ; // 123456789101112131415161718192021222324252627 animación con la tecla ‘izquierda’, no necesitamos a la izquierda y la derecha como vamos a utilizar uno y darle la vuelta al spritethis.anims.create ({clave: ‘izquierda’, marcos: this.anims.generateFrameNumbers (jugador ‘{marcos: [1,7,1,13]}), frameRate: 10, de repetición: -1}); // animación con la tecla ‘right’this.anims.create ({clave:’ derecho’, marcos : this.anims.generateFrameNumbers ( ‘jugador’, {marcos: [1,7,1,13]}), frameRate: 10, de repetición: -1}); this.anims.create clave ({: ‘up’, marcos: this.anims.generateFrameNumbers ( ‘jugador’, {marcos: [2,8,2,14]}), frameRate: 10, de repetición: -1}); this.anims.create ({clave: ‘abajo’ , marcos: this.anims.generateFrameNumbers ( ‘jugador’, {marcos: [0,6,0,12]}), frameRate: 10, de repetición: -1});

      El código anterior define un montón de animaciones , uno para cada dirección. En nuestro caso no necesitamos animaciones independientes para la izquierda y la derecha como nos limitaremos a voltear el sprite y el uso de los mismos marcos.

      En el método de actualización tiene que cambiar en la animación correcta. Añadir este código al final del método de actualización para hacerlo:
      si (this.cursors.left.isDown) {this.player.anims.play ( ‘izquierda’, true); } Else if (this.cursors.right.isDown) {this.player.anims.play ( ‘derecho’, true); } Else if (this.cursors.up.isDown) {this.player.anims.play ( ‘arriba’, true); } Else if (this.cursors.down.isDown) {this.player.anims.play ( ‘abajo’, true); } Else {this.player.anims.stop (); } 1234567891011121314151617181920if (this.cursors.left.isDown) {this.player.anims.play ( ‘izquierda’, true);} elseif (this.cursors.right.isDown) {this.player.anims.play ( ‘derecho’ , true);} elseif (this.cursors.up.isDown) {this.player.anims.play ( ‘arriba’, true);} elseif (this.cursors.down.isDown) {this.player.anims.play ( ‘abajo’, true);} else {this.player.anims.stop ();}

      Ahora bien, si todo es correcto, usted debe tener la animación agradable pasos en cada dirección. Sin embargo, nuestro jugador camina sobre los árboles y obstáculos. Tenemos que hacer que chocan con los azulejos en la capa de Obstáculos. Para ello, agregue esta fila al final de la WorldScene crear método:
      this.physics.add.collider (this.player, obstáculos); 1this.physics.add.collider (this.player, obstáculos);

      Se crea un objeto de la física colisionador y toma dos parámetros – en nuestro caso un sprite y una capa tilemap. Si recuerda que hicimos todas las fichas de los obstáculos capa
      llamada Collidable
      obstacles.setCollisionByExclusion ([- 1]);
      Ahora bien, si se intenta el juego se verá que el jugador puede mover ya no a través de obstáculos y tienen que evitarlos.
      Y su tiempo para pensar cómo el jugador se reunirá con los enemigos. Para las ubicaciones de los enemigos que he decidido utilizar un grupo de objetos de zona (Phaser.GameObjects.Zone). Cuando los solapamientos jugador con dicha zona, se iniciarán una batalla.

      Phaser.GameObjects.Zone es un objeto invisible, para poder verlo durante el desarrollo puede establecer de depuración: cierto como esto:
      la física: {default: ‘Arcade’, Arcade: {gravedad: {Y: 0}, depuración: true}}, 1234567physics: {default: ‘Arcade’, Arcade: {gravedad: {Y: 0}, depuración: true} },

      creará 30 zonas en un grupo de física y vamos a utilizar este grupo de prueba para las colisiones con el jugador.


      Añadir este código al final del método de crear WorldScene:
      this.spawns = this.physics.add.group ({ClassType: Phaser.GameObjects.Zone}); for (var i = 0; i <30; i ++) {var x = Phaser.Math.RND.between (0, this.physics.world.bounds.width); var y = Phaser.Math.RND.between (0, this.physics.world.bounds.height); // parámetros son x, y, ancho, this.spawns.create altura (x, y, 20, 20); } This.physics.add.overlap (this.player, this.spawns, this.onMeetEnemy, falso, this); 12345678this.spawns = this.physics.add.group ({ClassType: Phaser.GameObjects.Zone}); para (vari = 0; i <30; i ++) {varX = Phaser.Math.RND.between (0, this.physics.world.bounds.width); varían = Phaser.Math.RND.between (0, this.physics .world.bounds.height); // parámetros son X, Y, anchura, heightthis.spawns.create (X, Y, 20,20);} this.physics.add.overlap (this.player, this.spawns, this.onMeetEnemy, falso, este);

      Con la última fila que hacen que el jugador y nuestras zonas interactúan. Cuando el jugador se solapa con una de las zonas, se llama al método onMeetEnemy. Ahora tenemos que añadir este método para la WorldScene.
      onMeetEnemy: function (jugador, zona) {// iniciar la batalla}, 123onMeetEnemy: function (jugador, zona) {// iniciar la batalla},

      En la segunda parte de este tutorial vamos a llamar a la escena de batalla de aquí. Por ahora nuestra onMeetEnemy será más simple. Vamos a mover la zona a otra ubicación aleatoria. Para recoger azar coordino voy a utilizar Phaser.Math.RND.between (min, max).

      Cambiar el código onMeetEnemy a esto:
      onMeetEnemy: function (jugador, zona) {// movemos la zona a algún otro lugar zone.x = Phaser.Math.RND.between (0, this.physics.world.bounds.width); zone.y = Phaser.Math.RND.between (0, this.physics.world.bounds.height); // iniciar la batalla}, 1234567onMeetEnemy: function (jugador, zona) {// que mover la zona a alguna otra locationzone.x = Phaser.Math.RND.between (0, this.physics.world.bounds.width); zona .y = Phaser.Math.RND.between (0, this.physics.world.bounds.height); // iniciar la batalla},

      no vamos a destruir la zona, pero vamos a moverlo a otra ubicación aleatoria. Para hacer que la batalla se inicia un poco más intimidante vamos a añadir algo fresco -. Un efecto sacudida
      efecto Shake en Phaser 3 se puede añadir a través de la cámara -. camera.shake (duración)
      onMeetEnemy: function (jugador, zona) {// movemos la zona a algún otro lugar zone.x = Phaser.Math.RND.between (0, this.physics.world.bounds.width); zone.y = Phaser.Math.RND.between (0, this.physics.world.bounds.height); // agite el this.cameras.main.shake mundo (300); // iniciar la batalla}, 12345678910onMeetEnemy: function (jugador, zona) {// que mover la zona a alguna otra locationzone.x = Phaser.Math.RND.between (0, this.physics.world.bounds.width); zona .y = Phaser.Math.RND.between (0, this.physics.world.bounds.height); // agitar el worldthis.cameras.main.shake (300); // iniciar la batalla},

      jugar un poco con el valor para cambiar la duración de este efecto. A modo de ejercicio se puede tratar de cambiar el efecto de flash o desvanecimiento.
      camera.flash (duración); camera.fade (duración); 12camera.flash (duración); camera.fade (duración);


      Y con esto, la primera parte del tutorial ha terminado. En la segunda parte vamos a crear nuestra escena y escena de batalla interfaz de usuario, y vamos a cambiar a ellos cuando se cumple un enemigo. Cuando la batalla ha terminado vamos a volver a nuestro WorldScene.

      Mensajes relacionados

Deja una respuesta

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