En la primera parte de este tutorial creamos la WorldScene, y en la segunda parte que hizo el BattleScene. Si no los ha leído recomiendo fuertemente para que lo haga antes de continuar. Ahora, en la tercera parte, vamos a combinar las dos escenas en un juego de trabajo.

Tabla de contenidos

El código fuente

Puede descargar los archivos de este 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

    Activos

    Todos los activos utilizados en este tutorial son A0 licencia. Los azulejos son creados por Kenney Vleugels y se pueden descargar en www.kenney.nl
    Reproductor de caracteres – https://opengameart.org/content/rpg-character-sprites
    Enemigos – https://opengameart.org/content/dragon-1

    Escena de conmutación

    Al principio, voy a tratar de simplificar y explicar la lógica de conmutación escena. Vamos a utilizar la versión final de la WorldScene de la primera parte del tutorial y vamos a crear BattleScene muy básico y UIScene.

    Obtenga su trabajo y luego editar WorldScene el objeto de configuración para agregar BattleScene y UIScene. Editar que se vea como esto:
    config var = {type: Phaser.AUTO, padre: ‘contenido’, anchura: 320, altura: 240, zoom: 2, PixelArt: true, la física: {default: ‘Arcade’, arcade: {gravedad: {y: 0 }, depuración: false // conjunto en true para ver zonas}}, escena: [BootScene, WorldScene, BattleScene, UIScene]}; juego var = new Phaser.Game (config); 12345678910111213141516171819202122varconfig = {type: Phaser.AUTO, los padres : ‘contenido’, anchura: 320, altura: 240, del mapa: 2, pixelArt: true, la física: {default: ‘Arcade’, Arcade: {gravedad: {y: 0}, depurar: false // set en true para ver zonas}}, escena: [BootScene, WorldScene, BattleScene, UIScene]}; vargame = newPhaser.Game (config);

    y aquí son nuestra simplificado BattleScene y UIScenes. Los usaremos para mostrar cómo el cambio de escena funcionará:
    var BattleScene = nuevo Phaser.Class ({Extiende: Phaser.Scene, initialize: función BattleScene () {Phaser.Scene.call (esto, {key: ‘BattleScene’});}, crear: function () {// set el fondo de la this.cameras.main.setBackgroundColor verde escena principal ( ‘RGBA (0, 200, 0, 0,5)’); // Run escena de interfaz de usuario al mismo tiempo this.scene.run ( ‘UIScene’);} }); var UIScene = nuevo Phaser.Class ({Extiende: Phaser.Scene, initialize: función UIScene () {Phaser.Scene.call (esto, {key: ‘UIScene’});}: function () {, crear this.graphics = this.add.graphics (); this.graphics.lineStyle (1, 0xffffff); this.graphics.fillStyle (0x031f4c, 1); this.graphics.strokeRect (2, 150, 90, 100); esta .graphics.fillRect (2, 150, 90, 100); this.graphics.strokeRect (95, 150, 90, 100); this.graphics.fillRect (95, 150, 90, 100); this.graphics.strokeRect ( 188, 150, 130, 100); this.graphics.fillRect (188, 150, 130, 100);}}); 12345678910111213141516171819202122232425262728293031323334353637383940414243varBattleScene = newPhaser.Class ({Extiende: Ph aser.Scene, initialize: functionBattleScene () {Phaser.Scene.call (esto, {clave: ‘BattleScene’});}, crear: function () {// establecer el fondo de la escena principal greenthis.cameras.main. setBackgroundColor ( ‘RGBA (0, 200, 0, 0,5)’); // Run Escena de interfaz de usuario al mismo timethis.scene.run ( ‘UIScene’);}}); varUIScene = newPhaser.Class ({Extiende: Phaser. Escena, initialize: functionUIScene () {Phaser.Scene.call (esto, {key: ‘UIScene’});}, crear: function () {this.graphics = this.add.graphics (); this.graphics.lineStyle (1,0xffffff); this.graphics.fillStyle (0x031f4c, 1); this.graphics.strokeRect (2,150,90,100); this.graphics.fillRect (2,150,90,100); this.graphics.strokeRect (95,150,90,100); this.graphics.fillRect (95,150,90,100); this.graphics.strokeRect (188,150,130,100); this.graphics.fillRect (188,150,130,100);}});

    Ahora tenemos que cambiar el WorldScene para iniciar el BattleScene. Cambio WorldScene onMeetEnemy como 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); // agite el this.cameras.main.shake mundo (300); // interruptor para BattleScene this.scene.switch ( ‘BattleScene’); }, 1234567891011onMeetEnemy: function (jugador, zona) {// movemos la zona a alguna otra locationzone.x = Phaser.Math.RND.between (0, this.physics.world.bounds.width); zone.y = Phaser .Math.RND.between (0, this.physics.world.bounds.height); // agitar el worldthis.cameras.main.shake (300); // interruptor para BattleScenethis.scene.switch ( ‘BattleScene’); },

    Si se ejecuta el juego ahora, se verá que, cuando el jugador golpea un enemigo invisible, comienza BattleScene. Y BattleScene controlará la UIScene. Vamos a ver cómo volver de nuevo a la WorldScene. Voy a crear un método BattleScene exitBattle:
    exitBattle: function () {this.scene.sleep ( ‘UIScene’); this.scene.switch ( ‘WorldScene’); }, 1234exitBattle: function () {this.scene.sleep ( ‘UIScene’); this.scene.switch ( ‘WorldScene’);},

    Esta función va a dormir el UIScene (hacerlo no está activo y no es visible) y va a cambiar de BattleScene a WorldScene. Por ahora voy a añadir evento de tiempo simple que llamar a esta función después de 2 segundos.
    Esto, unido al extremo de crear BattleScene método:
    var timeEvent = this.time.addEvent ({retardo: 2000, de devolución de llamada: this.exitBattle, callbackScope: esta}); 1vartimeEvent = this.time.addEvent ({retardo: 2000, de devolución de llamada: this.exitBattle, callbackScope: esta}) ;

    Ahora que tenemos un problema. Todo funciona sólo la primera vez que nos cambiamos a BattleScene. La segunda vez, su función de crear no se llama así que no tenemos UIScene visibles y no salir BattleScene después del tiempo establecido.
    Para solucionar este problema tenemos que escuchar al evento Escena ‘despertar’. Añadir este código al final de la función de crear BattleScene:
    this.sys.events.on ( ‘despertar’, this.wake, this); 1this.sys.events.on ( ‘despertar’, this.wake, this);

    tenemos que añadir la función de encendido. Se ejecutará la UIScene y añadirá un evento programado para salir del BattleScene:
    despertar: function () {this.scene.run ( ‘UIScene’); this.time.addEvent ({retardo: 2000, callback: this.exitBattle, callbackScope: esta}); }, 1234wake: function () {this.scene.run ( ‘UIScene’); this.time.addEvent ({retraso: 2000, devolución de llamada: this.exitBattle, callbackScope: esta});},

    Ahora nuestro sencillo BattleScene debería funcionar bien cada vez que entramos en una batalla.

    Hacer funcionar el juego

    Es hora de cambiar el código BattleScene a la de la segunda parte de este tutorial. Retire sólo su BootScene ya que no necesitamos dos escenas de arranque para cargar nuestro juego. Es posible que tenga que añadir los recursos de los enemigos al cargador BootScene actual.
    // enemigos this.load.image ( «dragonblue», «activos / dragonblue.png»); this.load.image ( «dragonorrange», «activos / dragonorrange.png»); 123 // enemiesthis.load.image ( «dragonblue», «activos / dragonblue.png»); this.load.image ( «dragonorrange» «activos / dragonorrange.png»);

    Es hora de cambiar la clase de la siguiente manera:
    Unidad var = new Phaser.Class ({Extiende: Phaser.GameObjects.Sprite, initialize: Función Unidad (escena, x, y, textura, marco, el tipo, CV, daños) {Phaser.GameObjects.Sprite.call (esto, escena , x, y, textura, marco) this.type type =; this.maxHp = this.hp = hp; this.damage = daño; // daño this.living default = true; this.menuItem = null;}, / / vamos a utilizar esta para notificar a la opción de menú cuando la unidad está EstablecerElementoDelMenú muertos: la función (elemento) {this.menuItem = elemento;}, // atacar el ataque unidad objetivo: la función (objetivo) {if (target.living) { target.takeDamage (this.damage); this.scene.events.emit ( «Message», this.type + «ataques» + target.type + «para» «daño» + this.damage +);}}, takeDamage : function (daño) {this.hp – = daño; si (this.hp <= 0) {this.hp = 0; this.menuItem.unitKilled (); this.living = false; this.visible = false; este .menuItem = null;}}}); 1234567891011121314151617181920212223242526272829303132333435varUnit = newPhaser.Class ({Extiende: Phaser.GameObjects.Sprite, initialize: functionU nit (escena, x, y, textura, marco, tipo, hp, daños) {Phaser.GameObjects.Sprite.call (esto, escena, x, y, textura, marco) this.type = Tipo; this.maxHp = esta .HP = CV; this.damage = daños; // daños this.living default = true; this.menuItem = null;}, // vamos a usar esto para notificar a la opción de menú cuando la unidad está deadsetMenuItem: función (elemento) {this.menuItem = item;}, // atacar el unitattack objetivo: function (objetivo) {if (target.living) {target.takeDamage (this.damage); this.scene.events.emit ( "Message", este .Type + "ataques "+ target.type +" para "+ this.damage +" daño");}}, takeDamage: function (daño) {this.hp- ​​= daño; si (this.hp <= 0) {esto. CV = 0; this.menuItem.unitKilled (); this.living = false; this.visible = false; this.menuItem = null;}}});

    A continuación verá la variable menuItem. Vamos a vincular cada unidad a su elemento de menú, y cuando la unidad está muerto, se le notificará el elemento de menú para esto, por lo que el jugador no será capaz de seleccionar un enemigo muerto.
    También tenemos una nueva variable miembro – vida. Lo vamos a utilizar para comprobar si la unidad actual está vivo. Sólo las unidades que viven serán capaces de participar en la batalla.

    Ahora tenemos que editar el siguiente círculo ataque unidad de tomar en consideración esta nueva propiedad. Cambiar método BattleScene nextTurn a esto:
    nextTurn: function () {{hacer this.index ++; // si no hay más unidades, se comienza de nuevo desde el primero si (this.index> = this.units.length) {this.index = 0; }} While (this.units [this.index] .living); // si el jugador a su héroe si (this.units [this.index] instanceof PlayerCharacter) {this.events.emit ( «PlayerSelect», this.index); } Else {// else if su unidad enemiga // escoger al azar héroe var = r Math.floor (Math.random () * this.heroes.length); // Llamar al enemigo «s this.units función de ataque [this.index] .attack (this.heroes [r]); // temporizador complemento para la próxima vez, por lo que tendrá que suavizar juego this.time.addEvent ({retardo : 3000, devolución de llamada: this.nextTurn, callbackScope: esta});}}, 123456789101112131415161718192021nextTurn: function () {{hacer this.index ++; // si no hay más unidades, se comienza de nuevo desde el primer oneif (this.index > = this.units.length) {this.index = 0;}} while (this.units [this.index] .living); // si su reproductor heroif (this.units [this.index] instanceofPlayerCharacter) {este .events.emit ( «PlayerSelect», this.index);} else {// else if su unidad enemiga // escoger al azar herovarr = Math.floor (Math.random () * this.heroes.length); // llamada función del enemigo «s this.units ataque [this.index] .attack (this.heroes [r]); // temporizador complemento para la próxima vez, por lo que tendrá que suavizar gameplaythis.time.addEvent ({retraso: 3000, devolución de llamada : this.nextTurn, callbackScope: esta});}},

    Aquí se incrementa el índice hasta que tengamos una unidad de vivienda. Las unidades que están muertos no serán capaces de moverse más. Pero ahora tenemos un problema. Tendremos ciclo sin fin si no hay unidades de vivienda. Para evitar esto, hay que comprobar si hay más de juego o la victoria.

    Añadir este código en la parte superior de nextTurn:
    si (this.checkEndBattle ()) {this.endBattle (); regreso; } 1234if (this.checkEndBattle ()) {this.endBattle (); return;}

    Y aquí es cómo checkEndBattle debe ser:
    checkEndBattle: función) {victoria var (= true; // si todos los enemigos están muertos tenemos la victoria for (var i = 0; i Y aquí es endBattle:
    endBattle: function () {// estado claro, remove sprites this.heroes.length = 0; this.enemies.length = 0; for (var i = 0; i La versión final de nextTurn:
    nextTurn: function () {// si tenemos la victoria o juego sobre si (this.checkEndBattle ()) {this.endBattle (); regreso; } Do {// unidad activa en ese momento this.index ++; // si no hay más unidades, se comienza de nuevo desde el primero si (this.index> = this.units.length) {this.index = 0; }} While (this.units [this.index] .living!); // si su héroe jugador si (this.units [this.index] instanceof PlayerCharacter) {// necesitamos el jugador para seleccionar una acción y luego enemigo this.events.emit ( «PlayerSelect», this.index); } Else {// else if su unidad enemiga // recoger héroe vivo al azar para ser atacado var r; do {r = Math.floor (Math.random () * this.heroes.length); } While (this.heroes [r] .living!) // llamada a la función de ataque del enemigo this.units [this.index] .attack (this.heroes [r]); // temporizador complemento para la próxima vez, por lo que tendrá que suavizar juego this.time.addEvent ({retraso: 3000, devolución de llamada: this.nextTurn, callbackScope: esta}); }}, 123456789101112131415161718192021222324252627282930nextTurn: function () {// si tenemos la victoria o juego overif (this.checkEndBattle ()) {this.endBattle (); return;} do {// unitthis.index actualmente activo ++; // si hay hay más unidades, se comienza de nuevo desde el primer oneif (this.index> = this.units.length) {this.index = 0;}} while (this.units [this.index] .living!); // si su reproductor de heroif (this.units [this.index] instanceofPlayerCharacter) {// necesitamos el jugador para seleccionar una acción y luego enemythis.events.emit ( «PlayerSelect», this.index);} else {// else if su enemigo // unidad de recoger héroe vivo al azar para ser attackedvarr; do {r = Math.floor (Math.random () * this.heroes.length);} while (! this.heroes [r] .living) // llamar a los del enemigo función this.units de ataque [this.index] .attack (this.heroes [r]); // temporizador add para la próxima vez, por lo que tendrá suavizar gameplaythis.time.addEvent ({retardo: 3000, de devolución de llamada: this.nextTurn , callbackScope: esta});}},

    Como hemos visto desde la versión simple de BattleScene necesitamos escuchar para el suceso de activación. He creado nueva función startBattle y se trasladó más de la lógica a partir de ahí. Aquí es cómo mi aspecto startBattle:
    startBattle: function () {// personaje del jugador – guerrero var guerrero = new PlayerCharacter (esto, 250, 50, «jugador», 1, «Guerrero», 100, 20); this.add.existing (guerrero); // personaje del jugador – mage var mage = new PlayerCharacter (esto, 250, 100, «jugador», 4 «Mage», 80, 8); this.add.existing (mage); dragonblue var = nuevo enemigo (esto, 50, 50, «dragonblue», null, «Dragón», 50, 3); this.add.existing (dragonblue); var dragonOrange = new Enemy (esto, 50, 100, «dragonorrange», null, «Dragon2», 50, 3); this.add.existing (dragonOrange); // matriz con héroes this.heroes = [guerrero, mago]; // matriz con enemigos this.enemies = [dragonblue, dragonOrange]; // matriz con ambas partes, que atacarán this.units = this.heroes.concat (this.enemies); this.index = -1; // unidad this.scene.run actualmente activo ( «UIScene»); }, 1234567891011121314151617181920212223242526startBattle: function () {// personaje del jugador – warriorvarwarrior = newPlayerCharacter (esto, 250,50, «jugador», 1, «Guerrero», 100,20); this.add.existing (guerrero); // jugador personaje – magevarmage = newPlayerCharacter (esto, 250,100, «jugador», 4 «mago», 80,8); this.add.existing (mago); vardragonblue = newEnemy (esto, 50,50, «dragonblue», null, «dragón», 50,3); this.add.existing (dragonblue); vardragonOrange = newEnemy (esto, 50.100, «dragonorrange», null, «Dragon2», 50,3); this.add.existing (dragonOrange); // array con heroesthis.heroes = [guerrero, mago]; // array con enemiesthis.enemies = [dragonblue, dragonOrange]; // array con ambas partes, la OMS attackthis.units = this.heroes.concat (this.enemies ); this.index = -1; unitthis.scene.run // actualmente activo ( «UIScene»);},

    Y aquí es cómo el BattleScene crear cambios de función:
    crear: function () {// cambiar el fondo a this.cameras.main.setBackgroundColor verde ( «RGBA (0, 200, 0, 0,5)»); this.startBattle (); // en el evento de reactivación que llamamos startBattle demasiado this.sys.events.on ( ‘despertar’, this.startBattle, este); }, 1234567create: function () {// cambiar el fondo a greenthis.cameras.main.setBackgroundColor ( «RGBA (0, 200, 0, 0,5)»); this.startBattle (); // el evento de reactivación que llamamos startBattle toothis.sys.events.on ( ‘despertar’, this.startBattle, this);},

    Ahora vamos a cambiar la clase MenuItem como esto:
    var MenuItem = new Phaser.Class ({Extiende: Phaser.GameObjects.Text, initialize: función MenuItem (x, y, texto, escena) {Phaser.GameObjects.Text.call (esto, escena, x, y, texto, { Color: «#ffffff», align: «izquierda», fontSize: 15});}, seleccione: function () {this.setColor ( «# f8ff38″);}, para deshacer la selección: function () {this.setColor (» #ffffff «);}, // cuando la unidad enemigo o jugador asociado se mató unitKilled: function () {this.active = false; this.visible = false;}}); 1234567891011121314151617181920212223varMenuItem = newPhaser.Class ({extiende: Phaser .GameObjects.Text, initialize: functionMenuItem (x, y, texto, escena) {Phaser.GameObjects.Text.call (esto, escena, x, y, texto, {color: «# ffffff», align: «izquierda», fontSize: 15});}, seleccione: function () {this.setColor ( «# f8ff38»);}, para deshacer la selección: function () {this.setColor ( «# ffffff»);}, // cuando el enemigo asociada o unidad de jugador es killedunitKilled: function () {this.active = false; this.visible = false;}});

    Aquí se puede ver el método unitKilled llamado por las unidades de morir. Esto desactivará y ocultar el elemento de menú. Ahora hay que cambiar el menú de navegación, por lo que cuando la selección se mueve hacia arriba o hacia abajo, se saltará los elementos desactivados.
    Aquí es cómo cambiar el tipo de menú y moveSelectionUp moveSelectionDown:
    moveSelectionUp: function () {this.menuItems [this.menuItemIndex] .deselect (); do {this.menuItemIndex–; si (this.menuItemIndex <0) this.menuItemIndex = this.menuItems.length - 1; } While (this.menuItems [this.menuItemIndex] .active!); this.menuItems [this.menuItemIndex] .select (); }, MoveSelectionDown: function () {this.menuItems [this.menuItemIndex] .deselect (); do {this.menuItemIndex ++; si (this.menuItemIndex> = this.menuItems.length) this.menuItemIndex = 0; } While (this.menuItems [this.menuItemIndex] .active!); this.menuItems [this.menuItemIndex] .select (); }, 123456789101112131415161718moveSelectionUp: function () {this.menuItems [this.menuItemIndex] .deselect (); do {this.menuItemIndex -; si (this.menuItemIndex <0) this.menuItemIndex = this.menuItems.length-1;} mientras que; this.menuItems [this.menuItemIndex] .select ();}, moveSelectionDown (this.menuItems [this.menuItemIndex] .active!): function () {[this.menuItems this.menuItemIndex] .deselect (); hacen {this.menuItemIndex ++; si (this.menuItemIndex> = this.menuItems.length) this.menuItemIndex = 0;} while (this.menuItems [this.menuItemIndex] .active!); this.menuItems [this.menuItemIndex] .select ();},

    es necesario cambiar el método de selección también, así que cuando se activa el menú, se selecciona un elemento activo:
    seleccionar: función (índice) {if (! índice) index = 0; this.menuItems [this.menuItemIndex] .deselect (); this.menuItemIndex = índice; while (! this.menuItems [this.menuItemIndex] .active) {this.menuItemIndex ++; si (this.menuItemIndex> = this.menuItems.length) this.menuItemIndex = 0; si retorno (this.menuItemIndex == index); } this.menuItems [this.menuItemIndex] .select (); this.selected = true; }, 123456789101112131415select: (índice)! Función (índice) {if índice = 0; this.menuItems [this.menuItemIndex] .deselect (); this.menuItemIndex = índice; while (this.menuItems [this.menuItemIndex] .active ) {this.menuItemIndex ++; si (this.menuItemIndex> = this.menuItems.length) this.menuItemIndex = 0; si (this.menuItemIndex == índice) de retorno;} this.menuItems [this.menuItemIndex] .select (); this.selected = true;},

    Este es el momento de mención, que decidí cambiar el nombre de los SelectEnemies evento para SelectedAction. También, he cambiado los oyentes a Mach el nombre. Puede continuar con el antiguo nombre o usar la nueva. La mejor manera es usar simplemente reemplazar todo y su IDE hará todo automáticamente. A medida que el evento se activa cuando el jugador ha seleccionado una acción, creo que el código ahora es un poco más explica por sí mismo.

    Es necesario cambiar el método de reasignación de menús también:
    volver a asignar: función (unidades) {this.clear (); for (var i = 0; i Y el cambio de menú addMenuItem a esto:
    addMenuItem: function (unidad) {var menuItem = new MenuItem (0, this.menuItems.length * 20, unidad, this.scene); this.menuItems.push (menuItem); this.add (menuItem); volver menuItem; }, 123456addMenuItem: function (unidad) {varmenuItem = newMenuItem (0, this.menuItems.length * 20, unidad, this.scene); this.menuItems.push (menuItem); this.add (menuItem); returnmenuItem;},

    Ahora estamos casi hecho con los cambios. Lo que queda, es fijar la UIScene y la WorldScene para escuchar evento de reactivación. Voy a comenzar con el UIScene. El código que se encarga de la creación de menús global permanecerá en su método de crear, pero el código responsable de la batalla específica irá a la nueva función. Cambio UIScene crear método para esto:
    crear: function () {// sacar un poco de fondo para los this.graphics menú = this.add.graphics (); this.graphics.lineStyle (1, 0xffffff); this.graphics.fillStyle (0x031f4c, 1); this.graphics.strokeRect (2, 150, 90, 100); this.graphics.fillRect (2, 150, 90, 100); this.graphics.strokeRect (95, 150, 90, 100); this.graphics.fillRect (95, 150, 90, 100); this.graphics.strokeRect (188, 150, 130, 100); this.graphics.fillRect (188, 150, 130, 100); // recipiente de base para contener todos los menús this.menus = this.add.container (); this.heroesMenu = new HeroesMenu (195, 153, this); this.actionsMenu = new ActionsMenu (100, 153, este); this.enemiesMenu = new EnemiesMenu (8, 153, este); // el menú seleccionado en ese momento this.currentMenu = this.actionsMenu; // menús añadir a los contenedores this.menus.add (this.heroesMenu); this.menus.add (this.actionsMenu); this.menus.add (this.enemiesMenu); this.battleScene = this.scene.get ( «BattleScene»); // detectar eventos de teclado this.input.keyboard.on ( «keydown», this.onKeyInput, este); // cuando su reproductor de Cunit girar para mover this.battleScene.events.on ( «PlayerSelect», this.onPlayerSelect, este); // cuando se selecciona la acción en el menú // por ahora sólo tenemos una acción así que no enviamos y la acción Identificación del this.events.on ( «SelectedAction», this.onSelectedAction, este); // un enemigo se selecciona this.events.on ( «enemigo», this.onEnemy, este); // cuando la escena recibe evento de reactivación this.sys.events.on ( ‘despertar’, this.createMenu, este); // el mensaje que describe el this.message acción actual = mensaje nuevo (Esto, this.battleScene.events); this.add.existing (this.message); this.createMenu (); }, 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152create: function () {// dibujar algunos antecedentes para los menuthis.graphics = this.add.graphics (); this.graphics.lineStyle (1,0xffffff); this.graphics.fillStyle (0x031f4c, 1); esta .graphics.strokeRect (2,150,90,100); this.graphics.fillRect (2,150,90,100); this.graphics.strokeRect (95,150,90,100); this.graphics.fillRect (95,150,90,100); this.graphics.strokeRect (188,150,130,100 ); this.graphics.fillRect (188,150,130,100); // recipiente de base para contener todos menusthis.menus = this.add.container (); this.heroesMenu = newHeroesMenu (195.153, este); this.actionsMenu = newActionsMenu (100.153, este ); this.enemiesMenu = newEnemiesMenu (8153, this); // el menú seleccionado en ese momento this.currentMenu = this.actionsMenu; // añadir menús a la containerthis.menus.add (this.heroesMenu); this.menus.add ( this.actionsMenu); this.menus.add (this.enemiesMenu); this.battleScene = this.scene.get ( «BattleScene»); // escuchar para eventsthis.input.keyboard.on teclado ( «keydown», este .onKeyInput, this); // cuando su vez, el jugador Cunit a movethis.battleScene.events.on ( «PlayerSelect», this.onPlayerSelect, this); // cuando se selecciona la acción en el menú // por ahora sólo tenemos una acción por lo que no enviamos y la acción idthis.events.on ( «SelectedAction», this.onSelectedAction, this); // un enemigo es selectedthis.events.on ( «enemigo», this.onEnemy, this); // cuando la escena recibe estela eventthis.sys.events.on ( ‘estela’, this.createMenu, este); // el mensaje que describe el actionthis.message = newMessage (esto, this.battleScene.events) actual; this.add.existing (this.message); this.createMenu ();},

    Usted ve ahora que nosotros llamamos createMenu tanto cuando comenzamos la UIScene por primera vez y cuando su comenzado a través evento de reactivación. Aquí está nuestra createMenu:
    createMenu: function () {// Mapa héroe elementos de menú a los héroes this.remapHeroes (); // elementos de menú mapa enemigos a los enemigos this.remapEnemies (); // primero mover this.battleScene.nextTurn (); }, 12345678createMenu: function () {// Mapa héroe elementos de menú a heroesthis.remapHeroes (); // mapa enemigos elementos de menú para enemiesthis.remapEnemies (); // primera movethis.battleScene.nextTurn ();},

    después de ejecutar el juego ahora es posible encontrado un problema. Si su reproductor a su vez, y pulse el espacio de múltiples ocasiones en que la selección de un enemigo, nextTurn se llama varias veces y se puede presenciar un comportamiento extraño. Para solucionar este problema debemos estar seguros de que enviamos solamente un evento por menú. Para ello, he decido añadir una propiedad seleccionada a la clase Menu. Cuando se pone el foco Menú, esta propiedad se convierte en realidad. Cuando el jugador elige una acción, se convierte en falsa y el menú no tendrá su método de acción llamado de nuevo.
    Aquí es cómo la clase de menú debe mirar al final:
    var = new Menú Phaser.Class ({Extiende: Phaser.GameObjects.Container, inicialice: la función de menú (x, y, escena, héroes) {Phaser.GameObjects.Container.call (esto, escena, x, y); esto. MenuItems = []; this.menuItemIndex = 0; this.x = x; this.y = y; this.selected = false;}, addMenuItem: function (unidad) {var menuItem = new MenuItem (0, this.menuItems. longitud * 20, unidad, this.scene); this.menuItems.push (menuItem); this.add (menuItem); retorno menuItem;}, // menú moveSelectionUp de navegación: function () {this.menuItems [this.menuItemIndex] .deselect (); do {this.menuItemIndex–; si (this.menuItemIndex <0) = this.menuItemIndex this.menuItems.length - 1;} while (! this.menuItems [this.menuItemIndex] .active); este .menuItems [this.menuItemIndex] .select ();}, moveSelectionDown: function () {this.menuItems [this.menuItemIndex] .deselect (); do {this.menuItemIndex ++; si (this.menuItemIndex> = this.menuItems. longitud) this.menuItemIndex = 0;}, mientras que (this.menuItems [this.menuItemIndex] .active);! this.menuItems [this.menu ItemIndex] .select (); }, // seleccionar el menú en su conjunto y poner de relieve el elemento elegido seleccionar: función (índice) {if index = 0; (índice!) this.menuItems [this.menuItemIndex] .deselect (); this.menuItemIndex = índice; while (! this.menuItems [this.menuItemIndex] .active) {this.menuItemIndex ++; si (this.menuItemIndex> = this.menuItems.length) this.menuItemIndex = 0; si retorno (this.menuItemIndex == index); } this.menuItems [this.menuItemIndex] .select (); this.selected = true; }, // desactivar esta anular la selección de menú: function () {this.menuItems [this.menuItemIndex] .deselect (); this.menuItemIndex = 0; this.selected = false; }, Confirman: function () {// cuando el jugador confirma su slection, realizar la acción}, // menú claro y eliminar todos los elementos de menú clara: function () {for (var i = 0; i = this.menuItems.length) this.menuItemIndex = 0;} WHI Le (! this.menuItems [this.menuItemIndex] .active); this.menuItems [this.menuItemIndex] .select ();}, // seleccionar el menú en su conjunto y poner de relieve la elementselect elegido: function (índice) {if (! índice) index = 0; this.menuItems [this.menuItemIndex] .deselect (); this.menuItemIndex = índice; while (! this.menuItems [this.menuItemIndex] .active) {this.menuItemIndex ++; si (esto. menuItemIndex> = this.menuItems.length) this.menuItemIndex = 0; si (this.menuItemIndex == índice) de retorno;} this.menuItems [this.menuItemIndex] .select (); this.selected = true;}, // desactive esta menudeselect: function () {this.menuItems [this.menuItemIndex] .deselect (); this.menuItemIndex = 0; this.selected = false;}, confirman: function () {// cuando el jugador confirma su slection, hacer la acción}, menú // clara y eliminar todo el menú itemsclear: function () {for (vari = 0; i Y aquí cómo vamos a cambiar el UIScene onKeyInput:
    onKeyInput: function (evento) {if (this.currentMenu && this.currentMenu.selected) {if (event.code === «ArrowUp») {this.currentMenu.moveSelectionUp (); } Else if (event.code === «ArrowDown») {this.currentMenu.moveSelectionDown (); } Else if (event.code === «ArrowRight» || event.code === «Shift») {} else if (event.code === «espacio» || event.code === «arrowleft» ) {this.currentMenu.confirm (); }}}, 12345678910111213onKeyInput: function (evento) {if (this.currentMenu && this.currentMenu.selected) {if (event.code === «ArrowUp») {this.currentMenu.moveSelectionUp ();} elseif (event.code === «ArrowDown») {this.currentMenu.moveSelectionDown ();} elseif (event.code === «ArrowRight» || event.code === «Shift») {} elseif (event.code === «Espacio» || event.code === «arrowleft») {this.currentMenu.confirm ();}}},

    Ahora, cuando se ejecuta el juego casi todo debería funcionar bien. Pero a veces cuando vuelva a partir BattleScene a WorldScene, el personaje no está esperando pacientemente, sino que se mueve en alguna dirección y hay que presionar y soltar la tecla para esta dirección para detenerlo. Su pequeño fallo, pero tenemos que solucionarlo. Tenemos que esperar a que evento de reactivación WorldScene y luego restablecer las claves.

    Añadir esta fila hasta el final de WorldScene crear función:
    this.sys.events.on ( ‘despertar’, this.wake, this); 1this.sys.events.on ( ‘despertar’, this.wake, this);

    Y aquí es cómo el método de raíz debe mirar :
    despertar: function () {this.cursors.left.reset (); this.cursors.right.reset (); this.cursors.up.reset (); this.cursors.down.reset (); }, 123456wake: function () {this.cursors.left.reset (); this.cursors.right.reset (); this.cursors.up.reset (); this.cursors.down.reset ();},

    con esto hemos terminado con la tercera parte del tutorial. Aunque hemos hecho un montón de trabajo, nuestro juego necesita mucho más trabajo para ser completamente funcional. Get it as an exercise to save the state of the player characters and to make them get experience and levels. Also you can add more actions to the Actions menu and pass them together with the events.

    Mensajes relacionados

Deja una respuesta

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