El desarrollo del juego es un trabajo duro. Al igual que cualquier forma de desarrollo de software no van a ser errores en el código. eliminar errores de juegos puede ser especialmente difícil debido a su naturaleza de ritmo rápido en tiempo real. Afortunadamente, Phaser viene con un buen número de herramientas integradas en ayuda a depurar los juegos. Aparte de la lectura de la documentación de la API o mirar el código fuente de ejemplos, no hay una gran cantidad de detalles adicionales sobre cómo depurar ellos por ahí. En esta guía, voy a explicar lo que está disponible, y algunas formas del mundo real para los utilizan para combatir el ataque de los insectos de código.

Tabla de contenidos

Acerca de los ejemplos de código fuente

Todos los ejemplos de código fuente utilizados en este tutorial están disponibles en este archivo zip. A lo largo del tutorial voy a utilizar ES2015 Características (ES6) JavaScript. Al escribir estas líneas, no todas estas características son fácilmente disponibles en todos los navegadores todavía. El proyecto que he creado jspm usos y Babel para permitir el uso de estas características ahora. Si no está familiarizado con ES2015, recomiendo Explorando ES6, un libro electrónico que es una referencia fantástica sobre el tema.

Aprender Phaser mediante la construcción de 15 juegos

Si usted quiere dominar Phaser y aprender cómo publicar juegos Phaser como juegos nativas para iOS y Android se sienten libres para comprobar Zenva En línea En este supuesto The Complete el juego para móvil Curso de Desarrollo – Construir 15 juegos.

El objeto de depuración

Phaser viene incorporado con una instancia de una clase de depuración unido a cada juego. Siempre está ahí aunque si no lo usa (por lo que es llegar a ser marcado como “sucio”) que no afectará a su rendimiento. El objeto de depuración funciona dibujando varias informaciones, formas, etc a un lienzo. En el caso de un procesador basado lienzo, que utiliza el mismo contexto que la lona del juego. En el caso de WebGL, se necesita crear un nuevo lienzo y hacer de todo, desde el lienzo a un objeto sprite para superponer sobre la pantalla del juego. En ambos casos (aunque especialmente cierto para WebGL) las funciones de depuración debe ser utilizado sólo para depurar y desactivadas cuando se envía la versión real del juego.

En el desarrollo de aplicaciones JavaScript en el navegador, es posible que se utiliza para el uso de la salida de la consola desarrollador para obtener información de depuración. El problema con el uso que para los juegos es que la información que más a menudo se preocupan por que se actualiza cada fotograma en lugar de basarse en eventos. Si nos vamos a la salida de la posición del sprite por ejemplo, sería desplazarse continuamente la consola y que no sería capaz de controlar las cosas con mucha facilidad. Esta es la razón por la capacidad de hacer que la información de depuración en nuestra pantalla de juego es tan importante.

texto

Probablemente la herramienta más simple para la depuración está llegando texto arbitrario a la pantalla. El primer parámetro es el texto que desea mostrar. A continuación, tiene que pasar en las coordenadas X e Y que desea que el texto a empezar. También se puede pasar un color e información de fuente en si lo desea.
render () {this.game.debug.text ( `depuración Phaser $ {}` Phaser.VERSION, 20, 20, ‘amarillo’, ‘Segoe interfaz de usuario’);} 123render () {this.game.debug.text ( `DebuggingPhaser $ {}` Phaser.VERSION, 20,20, ‘amarillo’, ‘Segoe interfaz de usuario’);}

Otra forma de dibujar texto a la pantalla está utilizando el método de línea. Éste se utiliza realmente “internamente” por muchos de los otros métodos de depuración Phaser. El objeto de depuración realiza un seguimiento de la posición actual del cursor de texto. Cada vez que la línea se llama utiliza la posición de ese cursor (x y coordenadas Y en la pantalla) y modifica la y de la “línea” al lado del texto. Hay dos métodos más compañero de este, de inicio y parada. Llamando comienzo con X & Y parámetros pasados ​​en establecerá el cursor para las líneas de depuración posteriores. Será también guardar el estado de la lona de manera que cualquier otra operación no se ven afectados, por lo que es importante llamar a la parada de nuevo cuando haya terminado. Se puede llamar al método de línea, sin haber llamado el método de arranque en primer lugar, sin embargo, no es recomendable ya que la posición del cursor será desconocido.
this.game.debug.start (20, 20, ‘azul’); this.game.debug.line (); this.game.debug.line ( ‘Primera línea.’); this.game.debug.line ( ‘Segunda línea.’); this.game.debug.stop (); 12345this.game.debug.start (20,20, ‘azul’); this.game.debug.line (); this.game.debug. línea ( ‘Primera línea.’); this.game.debug.line ( ‘Segunda línea.’); this.game.debug.stop ();

cámara

Usted podría utilizar los métodos de texto y la línea a información en pantalla sobre las propiedades de una cámara en la pantalla, pero en su lugar otra construida en el método es cameraInfo. Este método muestra automáticamente la información sobre la posición de la cámara, los límites, y el número de sprites visibles (basado en la propiedad autoCull). Tiene que pasar en una referencia a la cámara que desea información sobre, y las coordenadas de partida para la información. Se prestará 4 líneas a partir de ese punto para mostrar todas las estadísticas.

Cámara Phaser depuración
this.game.debug.cameraInfo (this.game.camera, 32, 32); 1this.game.debug.cameraInfo (this.game.camera, 32,32);

Entrada

Por supuesto juegos son interactivos, así que ¿cómo se comportan los controles es muy importante. Phaser tiene varias formas de visualización de información acerca de los diversos insumos para fines de depuración.

Se puede mostrar información sobre una clave particular que se pulsa en el teclado utilizando el método clave. Se necesita una referencia a un objeto Phaser.Key, así como las coordenadas para mostrar la información.
// dentro de crear methodthis.testKey = game.input.keyboard.addKey (Phaser.KeyCode.SPACEBAR); // dentro render methodthis.game.debug.key (this.testKey, 32, 128); 12 345 // dentro de crear methodthis .testKey = game.input.keyboard.addKey (Phaser.KeyCode.SPACEBAR); // dentro rinden methodthis.game.debug.key (this.testKey, 32128);

Esta es la salida una tabla de información acerca de la clave incluyendo el código de la llave, si es o no isDown, si era justDown o justUp, así como una duración que se ha pulsado (si se mantiene pulsado).

Phaser Clave información de depuración

En general También vamos a obtener información de un ratón o cualquier otro puntero como el tacto. Por eso, Phaser también tiene otro método bien llamado puntero. Este se lleva una referencia al puntero que desea inspeccionar y eso es todo. La información que en realidad sigue el puntero alrededor en este caso.
this.game.debug.pointer (this.game.input.activePointer); 1this.game.debug.pointer (this.game.input.activePointer);

Phaser puntero de depuración

En este caso la línea blanca se inicia desde el último lugar el puntero se “hace clic” y se extiende a la posición actual (útil para arrastrar o deslizar). El círculo verde representa el puntero en sí y lo sigue alrededor. Cuando se mantiene presionado el botón, el contador de duración de las garrapatas arriba. (La imagen Fallo poco que hay sólo un sprite, que no forma parte de la información de depuración.)

Tal vez usted no necesita toda esa información siguiente alrededor del ratón, pero sólo tiene que saber dónde está, bueno, entonces estás de suerte, otro método más simple es el método inputInfo la que hace precisamente eso. Todo lo que necesitas para esto es que le indiquen dónde va a representar.
this.game.debug.inputInfo (32, 32); 1this.game.debug.inputInfo (32,32);

Phaser depuración InputInfo

Sprites

Sprites son uno de los objetos más importantes para cualquier juego Phaser, por lo que no es sorprendente, hay 4 métodos de depuración diseñados específicamente para ellos.

La primera es spriteInfo que muestra información sobre un sprite y su relación con el mundo. materia importante como su posición, ángulo, anclaje, límites, y si es o no es la vista de la cámara. Phaser depuración Sprite Info
this.game.debug.spriteInfo (sprite, 32, 32); 1this.game.debug.spriteInfo (sprite, 32,32);

Siguiente spriteCoords es todo acerca de la posición, donde el sprite está en la pantalla, y donde el sprite está en el mundo. Un poco menos detallado que spriteInfo, pero a veces todo lo que realmente necesita saber es donde el sprite. Phaser depuración Sprite Coords
this.game.debug.spriteCoords (sprite, 32, 128); 1this.game.debug.spriteCoords (sprite, 32.128);

Usted puede obtener información acerca de cómo un sprite se interactuó con por varios dispositivos de entrada utilizando spriteInputInfo. Se muestra un bloque de información en unas coordenadas al igual que spriteInfo, sin embargo esto es todo acerca de entrada. Para que éste funcione, el sprite en realidad necesita tener activadas las funciones de entrada, si no están en el momento en que se llama a este método, se obtendrá un error. Recuerde, por razones de rendimiento, los sprites no tienen entrada activadas por defecto, tiene que girar de forma explícita en la primera.

Phaser depuración Sprite de entrada
this.game.debug.spriteInputInfo (sprite, 32, 192); 1this.game.debug.spriteInputInfo (sprite, 32192);

límites Phaser depuración Sprite el último es el que spriteBounds rendirán un rectángulo alrededor del cuadro delimitador del sprite, lo que podría ser la imagen o el tamaño del sprite dentro de un spritesheet si se trata de una parte de uno.
this.game.debug.spriteBounds (sprites); 1this.game.debug.spriteBounds (sprites);

Sonidos

Un bloque pequeño pero muy útil para la visualización de información de sonido está disponible utilizando soundInfo. Éste le mostrará si el sonido se ha cargado y listo para usar por el navegador, si es o no está usando WebAudio, así como el tiempo que el sonido ha sido de juego y en qué volumen.
this.game.debug.soundInfo (this.splat, 32, 32, ‘amarillo’); 1this.game.debug.soundInfo (this.splat, 32,32, ‘amarillo’);

Phaser depuración de sonido

Geometría

Geometría en Phaser generalmente se utiliza solamente para los propósitos de la lógica. Puede ser difícil, sin embargo para envolver su cerebro alrededor de los acontecimientos sin un componente visual. Aquí es donde el método de depuración geom entra en juego. Geom puede hacer un círculo, rectángulo, punto o línea. Además, hay otro método: rectángulo, que, ya que sugiere simplemente hace que un rectángulo. En cualquiera de los casos se puede pasar en una instancia de una de las clases de geometría adecuada de Phaser, o un objeto que tiene las propiedades necesarias para hacer que la forma. Para geom, si es sólo un objeto, se necesita pasar en un cuarto parámetro para hacerle saber qué tipo de forma que realmente es.
clase gamestate extiende Phaser.State {precarga () {this.game.load.image ( ‘bug’, ‘activos / bug.png’); } Create () {dejar que los bichos = = this.bugs this.game.add.group (); bugs.createMultiple (30, ‘bug’, », true); bugs.setAll ( ‘anchor.x’, 0,5); bugs.setAll ( ‘anchor.y’, 0,5); bugs.setAll ( ‘inputEnabled’, true); bugs.forEach (bug => {bug.position.set (this.game.rnd.integerInRange (0, this.game.width), this.game.rnd.integerInRange (0, this.game.height)); bug .detectRadius = 24;}); bugs.callAll ( ‘events.onInputDown.add’, ‘events.onInputDown’, this.onBugClick, este); this.currentBug = null; } OnBugClick (bug) {this.currentBug = bug; } Render () {if (this.currentBug) {this.game.debug.geom (nueva Phaser.Circle (this.currentBug.x, this.currentBug.y, this.currentBug.detectRadius * 2)); }}} {123456789101112131415161718192021222324252627282930classGameState extendsPhaser.State precarga () {this.game.load.image ( ‘error’, ‘activos / bug.png’);} create () {dejar que los bichos = = this.bugs this.game.add .Group (); bugs.createMultiple (30, ‘bug’, », true); bugs.setAll ( ‘anchor.x’, 0,5); bugs.setAll ( ‘anchor.y’, 0,5); bugs.setAll ( ‘inputEnabled’, true); bugs.forEach (bug => {bug.position.set (this.game.rnd.integerInRange (0, this.game.width), this.game.rnd.integerInRange (0, esto .game.height)); bug.detectRadius = 24;}); bugs.callAll ( ‘events.onInputDown.add’, ‘events.onInputDown’, this.onBugClick, este); this.currentBug = null;} onBugClick ( error) {this.currentBug = error;} render () {if (this.currentBug) {this.game.debug.geom (newPhaser.Circle (this.currentBug.x, this.currentBug.y, this.currentBug.detectRadius * 2));}}}

Además del método geom también hay un método de píxeles que le permitirá no renderiza como su nombre indica, un solo píxel de la pantalla. A diferencia de la prestación de un punto utilizando geom, no tiene por qué ser un objeto Phaser Point, en lugar de simplemente cualquier coordenadas arbitrarias en la pantalla. Se pasa en X & Y, el color para hacer que el píxel, así como el tamaño. El tamaño predeterminado es 2, y se le puede decir así que no es un solo píxel, es cierto, pero los que puede ser difícil de ver (tan pequeña) así que tiene sentido utilizar 2 o incluso 4.
this.game.debug.pixel (100, 100, ‘rojo’, 4); 1this.game.debug.pixel (100,100, ‘rojo’, 4);

Física

Phaser naves con tres diferentes opciones de física: Arcade, Ninja, y P2. Debido a que tienen una API unificada en realidad se puede utilizar todos ellos al mismo tiempo, si lo desea. Cada objeto de la física habilitada tendrá un atributo del cuerpo que contendrá una referencia al cuerpo de la física que se aplican fuerzas en cada sistema. Debido a que todos ellos tienen una propiedad cuerpo con atributos similares en él podemos pasar esa referencia cuerpo en debug.bodyInfo. Ese método hará que la información sobre la posición, velocidad, aceleración, gravedad, etc a la pantalla para que el cuerpo se ha pasado.

También puede resaltar el cuerpo de la física en la pantalla utilizando el método debug.body. Puesto que el cuerpo de la física es una forma lógica utilizada para la colisión, esto puede ser importante visualizar ya que no siempre puede coincidir con el sprite que está conectada.
clase gamestate extiende Phaser.State {init () {this.game.physics.startSystem (Phaser.Physics.ARCADE); this.game.physics.arcade.gravity.y = 1,000; this.game.physics.arcade.skipQuadTree = false; } Precarga () {this.game.load.image ( ‘error’, ‘activos / bug.png’); } Create () {dejar que los bichos = = this.bugs this.game.add.group (); bugs.enableBody = true; bugs.createMultiple (30, ‘bug’, », true); bugs.setAll ( ‘anchor.x’, 0,5); bugs.setAll ( ‘anchor.y’, 0,5); bugs.setAll ( ‘inputEnabled’, true); bugs.forEach (bug => {bug.position.set (this.game.rnd.integerInRange (0, this.game.width), this.game.rnd.integerInRange (0, this.game.height)); bug .detectRadius = 24;}); bugs.callAll ( ‘events.onInputDown.add’, ‘events.onInputDown’, this.onBugClick, este); bugs.forEach (bug => {//this.game.physics.arcade.enable(bug); bug.body.collideWorldBounds = true; bug.body.bounce.set (0,8); bug.body.velocity.x = Math.random () * 500 * (Math.random ()> 0,5 -1: 1?);}); bugs.setAll ( ‘body.drag.x’, 10); this.currentBug = bugs.getRandom (); } Update () {this.game.physics.arcade.collide (this.bugs, this.bugs); } OnBugClick (bug) {this.currentBug = bug; bug.body.velocity.y + = -1,000; bug.body.velocity.x + = Math.random () * 1,000 * (Math.random ()> 0,5 -1:? 1); } Render () {this.game.debug.quadTree (this.game.physics.arcade.quadTree); si (this.currentBug) {this.game.debug.body (this.currentBug); this.game.debug.bodyInfo (this.currentBug, 32, 32); }}} 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253classGameState extendsPhaser.State {init () {this.game.physics.startSystem (Phaser.Physics.ARCADE); this.game.physics.arcade.gravity.y = 1,000; this.game.physics.arcade.skipQuadTree = false;} precarga () {this.game.load.image ( ‘error’, ‘activos / bug.png’);} create () {dejar que los bichos = = this.bugs this.game.add.group () ; bugs.enableBody = true; bugs.createMultiple (30, ‘bug’, », true); bugs.setAll ( ‘anchor.x’, 0,5); bugs.setAll ( ‘anchor.y’, 0,5); insectos .setAll ( ‘inputEnabled’, true); bugs.forEach (bug => {bug.position.set (this.game.rnd.integerInRange (0, this.game.width), this.game.rnd.integerInRange (0 , this.game.height)); bug.detectRadius = 24;}); bugs.callAll ( ‘events.onInputDown.add’, ‘events.onInputDown’, this.onBugClick, este); bugs.forEach (bug => {//this.game.physics.arcade.enable(bug);bug.body.collideWorldBounds=true;bug.body.bounce.set(0.8);bug.body.velocity.x=Math.random()*500 * (Math.random ()> 0,5 -1:? 1);}); bugs.setAll ( ‘body.drag.x’, 10); this.currentBug = Bugs.getRandom ();} update () {this.game.physics.arcade.collide (this.bugs, this.bugs);} onBugClick (bug) {this.currentBug = bug; bug.body.velocity.y + = -1,000; bug.body.velocity.x + = Math.random () * 1,000 * (Math.random ()> 0,5 -1:? 1);} render () {this.game.debug.quadTree (esto. game.physics.arcade.quadTree), si (this.currentBug) {this.game.debug.body (this.currentBug); this.game.debug.bodyInfo (this.currentBug, 32,32);}}} < p> Otra cosa que podemos hacer es un árbol cuádruple. Si usted no está enterado, un árbol cuádruple es un algoritmo de partición espacial que puede ayudar a reducir el número de órganos que necesita para la prueba de colisiones (u otra información pertinente en términos espaciales). En Phaser, sólo existe como parte del sistema de la física Arcade, y está desactivado por defecto. Podemos habilitarla estableciendo game.physics.arcade.skipQuadTree = false; y luego cada cuerpo de la física se añadirá automáticamente a la quadtree. clase de árbol cuádruple Phaser sin embargo puede ser usada fuera del sistema de la física para cualquier propósito desea, y el procesador de depuración árbol cuádruple hará que cualquier árbol cuaternario derivado de esa clase.

Phaser Depuración Physics

Phaser también es compatible con el sistema de física Box2D a través de un plug-in de alta calidad disponible en el sitio web. Si usted tiene este plugin, hay 2 funciones integradas en el objeto de depuración para mostrar información acerca de los cuerpos Box2D. Los métodos son box2dBody y box2dWorld. Ambos se utilice el valor predeterminado Box2D procesador de lona de depuración, todo Phaser está haciendo es simplemente proporcionar acceso al contexto de la lona de depuración para Box2D. Si usted decide comprar este plugin viene con mucha más información y documentación.

Depuración en nuestros propios proyectos

Los métodos incorporados en el objeto de depuración a cubrir algunos de los más comunes, y también escenarios más básicas cuando se trata de obtener información de depuración acerca de su juego. Cuando estamos construyendo nuestros propios proyectos, no es probable que va a haber más información que usted necesita para ser capaz de ver que la Phaser puede anticipar. Aquí es donde los bloques básicos tales como texto y geom realmente entran en juego.

debe entonces sumergirse en el código fuente de Phaser (No es miedo, es sólo Javascript!) Y echar un vistazo a los detalles de la implementación de otros métodos, como spriteInfo.
spriteInfo: function (sprite, x, y, color) {this.start (x, y, color); this.line ( ‘Sprite:’ + ‘(‘ + sprite.width + ‘x’ + sprite.height + ‘) de anclaje:’ + sprite.anchor.x + ‘x’ + sprite.anchor.y); this.line ( ‘x:’ + sprite.x.toFixed (1) + ‘y:’ + sprite.y.toFixed (1)); this.line ( ‘ángulo:’ + sprite.angle.toFixed (1) + ‘rotación:’ + sprite.rotation.toFixed (1)); this.line ( ‘visible:’ + sprite.visible + ‘en la cámara:’ + sprite.inCamera); this.line ( ‘límites x:’ + sprite._bounds.x.toFixed (1) + ‘y:’ + sprite._bounds.y.toFixed (1) + ‘w:’ + sprite._bounds.width.toFixed ( 1) + ‘h:’ + sprite._bounds.height.toFixed (1)); this.stop (); } 12345678910111213spriteInfo: function (sprite, x, y, color) {this.start (x, y, color); this.line ( ‘Sprite: ‘+'(‘ + sprite.width +’ x ‘+ sprite.height +’) ancla: ‘+ sprite.anchor.x +’ x ‘+ sprite.anchor.y); this.line (‘ x: ‘+ sprite.x.toFixed (1) +’ y: ‘+ sprite.y.toFixed (1 )); this.line ( ‘ángulo: ‘+ sprite.angle.toFixed (1) +’ rotación: ‘+ sprite.rotation.toFixed (1)); this.line (‘ visible: ‘+ sprite.visible +’ en cámara: ‘+ sprite.inCamera); this.line (‘ límites x: ‘+ sprite._bounds.x.toFixed (1) +’ y: ‘+ sprite._bounds.y.toFixed (1) +’ w: ‘ + sprite._bounds.width.toFixed (1) + ‘h:’ + sprite._bounds.height.toFixed (1)); this.stop ();}

podemos ver que utilizan la referencia de sprites que pasar, así como la x y coordenadas y en combinación con el método de inicio que he mencionado al principio. Luego, utilizando el método de línea, rinda líneas de datos sobre el sprite a la pantalla.

Vamos a decir que nosotros no sólo queremos mostrar información de sprites de forma genérica, pero hemos creado un objeto Sprite y adjunta varias otras propiedades a la misma, para que sea representan el jugador en el juego. El método spriteInfo no nos da ningún detalle acerca de estas propiedades adicionales (que ni siquiera sabe lo que son!), Ni nos da ninguna información acerca de otras cosas que ya existen en un sprite como la salud y la vida máxima . En este ejemplo, el avión es el seguimiento de una gran cantidad de cosas diferentes, y nos va a querer estar en condiciones de informar sobre algunos de ellos.
dejar que las balas = game.add.group (); bullets.enableBody = true; bullets.physicsBodyType = Phaser.Physics.ARCADE; bullets.createMultiple (100, ‘bala’); bullets.setAll ( ‘anchor.x’, 0,5); bullets.setAll ( ‘anchor.y’, 0,5); bullets.setAll ( ‘outOfBoundsKill’, true); bullets.setAll ( ‘checkWorldBounds’, true); dejar plano = this.plane = this.game.add.sprite (200, 200, ‘plano’); plane.heal (Infinity); plane.anchor.setTo (0,5); plane.scale.setTo (0.5,0.5); this.game.physics.enable (plano, Phaser.Physics.ARCADE); // animación plane.animations.add ( ‘volar’); plane.animations.play ( ‘volar’, 30, true); plane.sounds = {motor: this.game.add.audio ( ‘plane_engine’), arma: this.game.add.audio ( ‘plane_gun’), Die: this.game.add.audio ( ‘boom’)} ; plane.sounds.engine.loopFull (0,35); plane.bullets = balas; plane.fireTimer = this.game.time.now; plane.events.onKilled.add (this.planeKilled, este); plane.score = {killsByCollision: 0, killsByShooting: 0}; balas 12345678910111213141516171819202122232425262728293031323334let = game.add.group (); bullets.enableBody = true; bullets.physicsBodyType = Phaser.Physics.ARCADE; bullets.createMultiple (100, ‘bala’ ); bullets.setAll ( ‘anchor.x’, 0,5); bullets.setAll ( ‘anchor.y’, 0,5); bullets.setAll ( ‘outOfBoundsKill’, true); bullets.setAll ( ‘checkWorldBounds’, true); dejó plano = this.plane = this.game.add.sprite (200200, ‘plano’); plane.heal (Infinity); plane.anchor.setTo (0,5); plane.scale.setTo (0.5,0.5); esta .game.physics.enable (plano, Phaser.Physics.ARCADE); // animationplane.animations.add ( ‘volar’); plane.animations.play ( ‘volar’, 30, true); plane.sounds = {motor : this.game.add.audio ( ‘plane_engine’), arma: this.game.add.audio ( ‘plane_gun’), die: this.game.add.audio ( ‘boom’)}; plane.sounds.engine .loopFull (0,35); plane.bullets = balas; plane.fireTimer = this.game.time.now; plane.events.onKilled.add (this.planeKilled, este); plane.score = {killsByCollision: 0, killsByShooting: 0};

con el fin de mostrar por lo Me información útil, necesitaremos crear un método de depuración personalizado. Tenga en cuenta que podemos mostrar retazos que podamos encontrar en otros métodos de depuración, así como nuestras propiedades personalizadas.
displayDebugInfo () {this.game.debug.start (32, 32); this.game.debug.line ( `Salud: $ {} this.plane.health / $ {}` this.plane.maxHealth); this.game.debug.line ( `FireTimer: $ {}` this.plane.fireTimer); this.game.debug.line ( `Pistola de sonido: $ {} this.plane.sounds.gun.currentTime como jugador: $ {}` this.plane.sounds.gun.isPlaying); this.game.debug.line ( `Plano Loc: ($ {} this.plane.x, $ {} this.plane.y)`); cuerpo var = this.plane.body; this.game.debug.line ( `cuerpo plano: [$ {body.x.toFixed (2)}, $ {body.y.toFixed (2)}] Anchura: $ {} body.width altura: $ {cuerpo .height} `); this.game.debug.line ( `mata: se topó con $ {} this.plane.score.killsByCollision y disparó $ {}` this.plane.score.killsByShooting); this.game.debug.stop (); this.game.debug.body (this.plane); this.game.debug.text ( ‘ancla’, this.plane.x + 4, this.plane.y, ‘rojo’); this.game.debug.pixel (this.plane.x, this.plane.y, ‘rojo’, 4); } 12345678910111213141516displayDebugInfo () {this.game.debug.start (32,32); this.game.debug.line ( `Salud: $ {} this.plane.health / $ {}` this.plane.maxHealth); este .game.debug.line ( `FireTimer: $ {}` this.plane.fireTimer); this.game.debug.line ( `Pistola de sonido: $ {} this.plane.sounds.gun.currentTime como jugador: $ {esto .plane.sounds.gun.isPlaying} `); this.game.debug.line (` Plano Loc: ($ {} this.plane.x, $ {} this.plane.y) `); varbody = esto. plane.body; this.game.debug.line ( `cuerpo plano: [$ {body.x.toFixed (2)}, $ {body.y.toFixed (2)}] anchura: $ {} body.width altura : $ {} `body.height); this.game.debug.line (` mata: raninto $ {} this.plane.score.killsByCollision andshot $ {} `this.plane.score.killsByShooting); this.game. debug.stop (); this.game.debug.body (this.plane); this.game.debug.text ( ‘ancla’, this.plane.x + 4, this.plane.y, ‘rojo’); this.game.debug.pixel (this.plane.x, this.plane.y, ‘rojo’, 4);}


Una cosa que inmediatamente me parece útil es la representación del cuerpo de anclaje y la física. En primer lugar, podemos ver que el ancla para el sprite no está realmente centrada en el plano sí mismo. También el cuerpo de la física no está centrada en el avión, así como lo está ocupando mucho más espacio del plano de imagen real que también. Esto significa que vamos a chocar con los enemigos a una distancia tal que no se va a sentir derecho de los jugadores. A partir de la información de texto del cuerpo del avión, podemos ver que la anchura y la altura son tanto 128. El tamaño real del plano (cada cuadro) es 176. Dado que también estoy escalando el plano a la mitad, parecería que tiene Phaser golpeado originalmente mi imagen hasta 256. Ahora sé dónde buscar para resolver el problema, algo que ver con el tamaño de la imagen.

utilicé Textura Packer para generar el sprite 3 marco para el plano a partir de 3 imágenes separadas. (Si usted no ha oído hablar de textura Packer, le recomiendo que se echa un vistazo, es una herramienta muy útil para hacer frente a un montón de sprites de una manera organizada y eficiente.) Me carga el JSON atlas de archivo que se genera en Phaser y este es el resultado que obtuve. Los originales eran 3 imágenes cada tamaño de 256 x 256 modo que es donde el tamaño era (Phaser no hizo nada para ellos). Parece estar leyendo el tamaño de la imagen de origen del archivo JSON. Como una prueba rápida, he pasado de Carga del archivo de JSON atlas de carga de un solo spritesheet y el suministro de las dimensiones para cada cuadro. Eso resuelto el problema, al menos en el caso de que sólo tengo 1 animación plano en la hoja, y todas las tramas son del mismo tamaño (lo cual es cierto en este caso). Miré en línea y encontré este mensaje en el foro en el que otro usuario estaba teniendo problemas similares. He descubierto que utilizando la función de “ajuste” de textura Packer fue el tema, Phaser utilizará el tamaño de fuente en este caso porque los sprites están siendo embalados a los efectos del consumo de memoria de imagen, pero todavía tienen que ser prestados como si fueran imágenes separadas. En mi caso, sin embargo, quiero usar el modo “cultivo”, ya que no quiero este comportamiento, quiero usarlo en forma empaquetada. Cambio de la salida a recortada hizo el truco! Ahora el cuerpo de colisión y la línea de anclaje hacia arriba, y todo está funcionando de la manera que quería.

Phaser Depuración - depurado

Con suerte se puede ver ahora cómo saber cómo mostrar la información acerca de su juego puede ayudar con la depuración. El proceso que acabo de ir a través yo no simular, en realidad creó la demostración para esta y encontró el problema con los sprites después de cumplir en las herramientas de depuración. (Funcionó muy bien para mí tener un problema real al escribir el tutorial)

He mencionado antes que tener esta información de depuración que muestra es caro, y por supuesto que no desea que se muestre en la versión final de su juego. Puede volver atrás y comentario o eliminar el código que muestra la información de depuración, pero que puede resultar tedioso después de un tiempo. En su lugar puede crear un simple bandera en el código que determina si debe o no mostrar.
init () {this.game.stage.disableVisibilityChange = true; this.debugMode = false; } 12345init () {this.game.stage.disableVisibilityChange = true; this.debugMode = false;}

Primero añado la prueba de la fase de inicio de mi estado. Entonces simplemente puede envolver el displayDebugInfo en un método condicional en el método render.
render () {if (this.debugMode) {this.displayDebugInfo (); }} 12345render () {if (this.debugMode) {this.displayDebugInfo ();}}

Puede alternar manualmente esa bandera que está en el método init, o puede también configurar una tecla para cambiar en tiempo de ejecución. Algo como esto debe hacer el truco:
toggleDebug () {this.debugMode = this.debugMode!; si (this.debugMode!) {this.game.debug.reset (); }} 123456toggleDebug () {this.debugMode = this.debugMode; if (! This.debugMode) {this.game.debug.reset ();}} // dentro createthis.debugKey = this.game.input.keyboard. ADDKEY (Phaser.Keyboard.D); this.debugKey.onDown.add (this.toggleDebug, este); 123 // dentro createthis.debugKey = this.game.input.keyboard.addKey (Phaser.Keyboard.D); esta .debugKey.onDown.add (this.toggleDebug, this);

Ahora usted debería ser capaz de activar y desactivar el modo de depuración utilizando la tecla D en el teclado (no dude en cambiarlo a lo que te gusta). Un método final de mención sobre el objeto de depuración en Phaser es el método de restablecimiento. Esto borrará el lienzo o la imagen de sprite de modo que incluso cuando el modo de depuración es “off” que no hacen lo último que se dicte. Recuerde, depurar siempre está ahí, simplemente no se puede ver hasta que comienza a dibujar a la superficie.

Id y Squash!

Gracias por tomarse el tiempo de leer esta guía sobre Phaser depuración. A medida que los desarrolladores de juegos (y desarrolladores de software) siempre tenemos errores que tratar, esperemos que esta guía le ayudará a ellos aplasta rápidamente. Por favor, deje sus comentarios o preguntas a continuación, o quisiera saber cómo ha utilizado las herramientas de depuración para salvar el día!

Mensajes relacionados
 Phaser inactivo clicker Tutorial bandera

Deja una respuesta

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