En mis dos últimos tutoriales que creó un juego Fruit Ninja y ha añadido algo de contenido a la misma. En este último tutorial, vamos a añadir un nuevo modo de juego. Esto implicará, en la adición de una pantalla de título, refactorización parte de nuestro código y añadir algo de contenido adicional. Voy a cubrir el siguiente contenido en este tutorial:


  • La adición de una fuente personalizada para todos los textos que se muestra
  • Adición de un nuevo modo de juego llamado Time Attack. En este modo, el jugador debe cortar tantas frutas como sea posible antes de que acabe el tiempo
  • Refactorizando el código de nuestros estados, a la reutilización entre los diferentes estados
  • La adición de una pantalla de título, donde el jugador puede elegir entre los dos modos de juego
  • La adición de dos cuttables casas prefabricadas para el modo Time Attack. El primero es un reloj, lo que aumenta el tiempo restante cuando se corta, y la segunda es una bomba de tiempo, lo que reduce el tiempo restante cuando se corta

    Para leer este tutorial, es importante que usted está familiarizado con los conceptos siguientes:


    • Javascript y conceptos orientados a objetos.
    • conceptos básicos Phaser, tales como: estados, sprites, los grupos y la física de arcade

      Tabla de contenidos

      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.

      Activos de derechos de autor

      El activo bomba usada en este tutorial fue hecho por Alucard bajo Creative Commons License (http://opengameart.org/content/bomb-2d), que permite el uso comercial con atribución.

      archivos de código fuente

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

      Juego Unidos

      utilizará los siguientes estados para ejecutar nuestro juego:


      • Estado de arranque: Carga un archivo JSON con la información de nivel y comienza la carga del Estado
      • Cargando Estado: carga todos los recursos del juego, y se inicia el siguiente estado
      • Título del estado: muestra la pantalla de título, lo que permite al jugador elegir entre los dos modos de juego: Clásico y Time Attack
      • Estado clásico: se ejecuta el modo de juego que estábamos trabajando en los dos últimos tutoriales, en el que los cortes jugador frutos hasta que se queda sin vidas
      • Time Attack Estado: nuevo modo de juego, donde los cortes jugador frutos hasta que se queda sin tiempo

        Hay una gran cantidad de cambios en los códigos de estados, ya que vamos a refactorizar el código para permitir que varios modos de juego. Así que, para simplificar, voy a mostrar los cambios que son necesarios.

        Refactorizando el código para añadir múltiples modos de juego

        Dado que vamos a tener múltiples estados, tenemos que identificar código común entre ellas y ponerla en otro estado, que se ampliará. Con el fin de hacer eso, vamos a crear los siguientes estados de padres a extenderse:


        • JSONLevelState: carga un archivo JSON ya que estábamos usando en los últimos tutoriales, con los activos, los grupos y las casas prefabricadas
        • LevelState: representa un nivel genérico. Es responsable de la detección de golpes, la comprobación de colisiones y que muestra la puntuación y el juego sobre la pantalla

          La jerarquía de estados se muestra en la figura siguiente. Tenga en cuenta que se extiende TitleState JSONLevelState, ya que vamos a iniciarlo desde un archivo JSON, pero no se extiende LevelState, ya que no es un estado del juego. Por otro lado, tanto ClassicState y TimeAttackState se extenderán LevelState, sobrescribir los métodos necesarios y añadiendo otros nuevos.

          fruit_ninja_states

          El código para JSONLevelState y LevelState se muestran abajo. JSONLevelState tiene el método “create_prefab” y el código para crear desde el archivo JSON. LevelState tiene el “start_swipe”, “end_swipe”, “check_collision”, “init_hud”, los métodos de “restart_level” “game_over” y. Tenga en cuenta que la variable de mayor puntuación puede ser diferente según el modo de juego, por lo que tenemos que salir de su nombre como una variable que se encuentra en otras implementaciones del estado, como se puede ver en el método “game_over”.
          var Fruit Ninja = Fruit Ninja || {}; FruitNinja.JSONLevelState = function () { «utilizar estricta»; Phaser.State.call (this); this.prefab_classes = {};}; FruitNinja.JSONLevelState.prototype = Object.create (Phaser.State.prototype); FruitNinja.JSONLevelState.prototype.constructor = FruitNinja.JSONLevelState; FruitNinja.JSONLevelState.prototype.init = function (level_data) { «utilizar estricta»; this.level_data = level_data; this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL; this.scale.pageAlignHorizontally = true; this.scale.pageAlignVertically = true;}; FruitNinja.JSONLevelState.prototype.create = function () { «utilizar estricta»; GROUP_NAME var, prefab_name; // crear grupos this.groups = {}; this.level_data.groups.forEach (function (GROUP_NAME) {this.groups [GROUP_NAME] = this.game.add.group ();}, this); // crear prefabricadas this.prefabs = {}; para (prefab_name en this.level_data.prefabs) {if (this.level_data.prefabs.hasOwnProperty (prefab_name)) {// crear prefabricada this.create_prefab (prefab_name, this.level_data.prefabs [prefab_name]); }}}; FruitNinja.JSONLevelState.prototype.create_prefab = function (prefab_name, prefab_data) { «utilizar estricta»; prefab_position var, prefabricada; // crear el objeto de acuerdo con su tipo si (this.prefab_classes.hasOwnProperty (prefab_data.type)) {if (prefab_data.position.x> 0 && prefab_data.position.x <= 1) {// posición como porcentaje prefab_position = new Phaser.Point (prefab_data.position.x * this.game.world.width, prefab_data.position.y * this.game.world.height); } Else {// posición como absoluta número prefab_position = prefab_data.position; } = prefabricadas nuevas this.prefab_classes [prefab_data.type] (Esto, prefab_name, prefab_position, prefab_data.properties); }}; 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758varFruitNinja = Fruit Ninja || {}; FruitNinja.JSONLevelState = function () { "utilizar estricta"; Phaser.State.call (this); this.prefab_classes = {};}; FruitNinja.JSONLevelState.prototype = Object. crear (Phaser.State.prototype); FruitNinja.JSONLevelState.prototype.constructor = FruitNinja.JSONLevelState; FruitNinja.JSONLevelState.prototype.init = function (level_data) { "utilizar estricta"; this.level_data = level_data; this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL; this.scale.pageAlignHorizontally = true; this.scale.pageAlignVertically = true;}; FruitNinja.JSONLevelState.prototype.create = function () { "utilizar estricta"; vargroup_name, prefab_name; // crear groupsthis .Grupos = {}; this.level_data.groups.forEach (function (GROUP_NAME) {this.groups [GROUP_NAME] = this.game.add.group ();}, this); // crear prefabsthis.prefabs = {} ; para (inthis.level_data.prefabs prefab_name) {if (this.level_data.prefabs.hasOwnProperty (prefab_name)) {// crear prefabthis.cre ate_prefab (prefab_name, this.level_data.prefabs [prefab_name]);}}}; FruitNinja.JSONLevelState.prototype.create_prefab = function (prefab_name, prefab_data) { "utilizar estricta"; varprefab_position, prefabricada; // crear el objeto de acuerdo con su typeif (this.prefab_classes.hasOwnProperty (prefab_data.type)) {if (prefab_data.position.x> 0 && prefab_data.position.x <= 1) {// posición como porcentaje prefab_position = new Phaser.Point (prefab_data.position.x * this.game.world.width, prefab_data.position.y * this.game.world.height);} else {// posición como numberprefab_position absoluta = prefab_data.position;} prefabricada = newthis.prefab_classes [prefab_data.type] (este , prefab_name, prefab_position, prefab_data.properties);}}; var Fruit Ninja = Fruit Ninja || {}; FruitNinja.LevelState = function () { "utilizar estricta"; FruitNinja.JSONLevelState.call (this); this.prefab_classes = {};}; FruitNinja.LevelState.prototype = Object.create (FruitNinja.JSONLevelState.prototype); FruitNinja.LevelState.prototype.constructor = FruitNinja.LevelState; FruitNinja.LevelState.prototype.init = function (level_data) { "utilizar estricta"; FruitNinja.JSONLevelState.prototype.init.call (esto, level_data); sistema de física this.game.physics.startSystem (Phaser.Physics.ARCADE) // empezar; this.game.physics.arcade.gravity.y = 1,000; this.MINIMUM_SWIPE_LENGTH = 50; this.score = 0;}; FruitNinja.LevelState.prototype.create = function () { "utilizar estricta"; FruitNinja.JSONLevelState.prototype.create.call (this); // añadir eventos para comprobar si hay golpe this.game.input.onDown.add (this.start_swipe, este); this.game.input.onUp.add (this.end_swipe, este); this.init_hud ();}; FruitNinja.LevelState.prototype.start_swipe = función (puntero) { "uso estricto"; this.start_swipe_point = new Phaser.Point (pointer.x, pointer.y);}; FruitNinja.LevelState.prototype.end_swipe = función (puntero) { "utilizar estricta"; var swipe_length, cut_style, corte; this.end_swipe_point = new Phaser.Point (pointer.x, pointer.y); swipe_length = Phaser.Point.distance (this.end_swipe_point, this.start_swipe_point); // si la longitud de golpe es mayor que el mínimo, se detecta un golpe si (swipe_length> = this.MINIMUM_SWIPE_LENGTH) {// crear una nueva línea que el golpe y comprobar las colisiones cut_style = {line_width: 5, color: 0xE82C0C, alpha: 1}; corte = nuevo FruitNinja.Cut (esto «corte», {x: 0, y: 0}, {grupo: «cortes», comenzar: this.start_swipe_point, final: this.end_swipe_point, duración: 0,3, el estilo: cut_style} ); this.swipe = new Phaser.Line (this.start_swipe_point.x, this.start_swipe_point.y, this.end_swipe_point.x, this.end_swipe_point.y); this.groups.fruits.forEachAlive (this.check_collision, este); this.groups.bombs.forEachAlive (this.check_collision, este); this.groups.special_fruits.forEachAlive (this.check_collision, este); this.groups.time_bombs.forEachAlive (this.check_collision, este); this.groups.clocks.forEachAlive (this.check_collision, este); }}; FruitNinja.LevelState.prototype.check_collision = función (objeto) { «utilizar estricta»; var object_rectangle, línea 1, línea 2, línea 3, line4, intersección; // crear un rectángulo para el cuerpo objeto object_rectangle = new Phaser.Rectangle (object.body.x, object.body.y, object.body.width, object.body.height); // cheque por intersecciones con cada línea 1 borde rectángulo = new Phaser.Line (object_rectangle.left, object_rectangle.bottom, object_rectangle.left, object_rectangle.top); line2 = new Phaser.Line (object_rectangle.left, object_rectangle.top, object_rectangle.right, object_rectangle.top); línea 3 = new Phaser.Line (object_rectangle.right, object_rectangle.top, object_rectangle.right, object_rectangle.bottom); line4 = new Phaser.Line (object_rectangle.right, object_rectangle.bottom, object_rectangle.left, object_rectangle.bottom); intersección = this.swipe.intersects (línea 1) || this.swipe.intersects (line2) || this.swipe.intersects (línea 3) || this.swipe.intersects (line4); si (intersección) {// si no se encuentra una intersección, cortar la object.cut objeto (); }}; FruitNinja.LevelState.prototype.init_hud = function () { «utilizar estricta»; var score_position, score_style, partitura; // crear anotar score_position prefabricada = new Phaser.Point (20, 20); score_style = {font: «48px Shojumaru», relleno: «#fff»}; puntuación = nueva FruitNinja.Score (esto, «puntuación», score_position, {texto: «Frutas», estilo: score_style, grupo: «HUD»});}; FruitNinja.LevelState.prototype.game_over = function () { » utilizar estricta «; var game_over_panel, game_over_position, game_over_bitmap, panel_text_style; // si la puntuación actual es superior a la puntuación más alta, que se actualizará si (localStorage [this.highest_score] || this.score> localStorage [this.highest_score]) {localStorage [this.highest_score] = this.score; } // crear un mapa de bits no mostrar el juego sobre game_over_position del panel = new Phaser.Point (0, this.game.world.height); game_over_bitmap = this.add.bitmapData (this.game.world.width, this.game.world.height); game_over_bitmap.ctx.fillStyle = «# 000»; game_over_bitmap.ctx.fillRect (0, 0, this.game.world.width, this.game.world.height); panel_text_style = {game_over: {font: «32px Shojumaru», relleno: «#FFF»}, current_score: {font: «20 píxeles Shojumaru», relleno: «#FFF»}, highest_score: {font: «18px Shojumaru», relleno : «#FFF»}}; // crear el juego sobre el panel game_over_panel = new FruitNinja.GameOverPanel (esto «game_over_panel», game_over_position, {textura: game_over_bitmap, grupo: «HUD», text_style: panel_text_style, animation_time: 500}); this.groups.hud.add (game_over_panel);}; FruitNinja.LevelState.prototype.restart_level = function () { «utilizar estricta»; this.game.state.restart (verdadero, falso, this.level_data);}; 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112varFruitNinja = Fruit Ninja || {}; FruitNinja.LevelState = function () { «utilizar estricta»; FruitNinja.JSONLevelState.call (this); esta .prefab_classes = {};}; FruitNinja.LevelState.prototype = Object.create (FruitNinja.JSONLevelState.prototype); FruitNinja.LevelState.prototype.constructor = FruitNinja.LevelState; FruitNinja.LevelState.prototype.init = function (level_data) { «use strict»; FruitNinja.JSONLevelState.prototype.init.call (esto, level_data); // iniciar la física systemthis.game.physics.startSystem (Phaser.Physics.ARCADE); this.game.physics.arcade.gravity.y = 1000; this.MINIMUM_SWIPE_LENGTH = 50; this.score = 0;}; FruitNinja.LevelState.prototype.create = function () { «utilizar estricta»; FruitNinja.JSONLevelState.prototype.create.call (this); // add eventos a CH eck para swipethis.game.input.onDown.add (this.start_swipe, este); this.game.input.onUp.add (this.end_swipe, este); this.init_hud ();}; FruitNinja.LevelState.prototype. start_swipe = función (puntero) { «utilizar estricta»; this.start_swipe_point = newPhaser.Point (pointer.x, pointer.y);}; FruitNinja.LevelState.prototype.end_swipe = función (puntero) { «utilizar estricta»; varswipe_length , cut_style, corte; this.end_swipe_point = newPhaser.Point (pointer.x, pointer.y); swipe_length = Phaser.Point.distance (this.end_swipe_point, this.start_swipe_point); // si la longitud de golpe es mayor que el mínimo , un golpe es detectedif (swipe_length> = this.MINIMUM_SWIPE_LENGTH) {// crear una nueva línea que el golpe y comprobar para collisionscut_style = {line_width: 5, color: 0xE82C0C, alfa: 1}; corte = newFruitNinja.Cut (esto, «corte», {x: 0, y: 0}, {grupo: «cortes», inicio: this.start_swipe_point, final: this.end_swipe_point, duración: 0,3, el estilo: cut_style}); this.swipe = newPhaser.Line (this.start_swipe_point.x, this.start_swipe_point.y, this.end_swipe_point.x, this.end_swipe_point.y); this.grou ps.fruits.forEachAlive (this.check_collision, este); this.groups.bombs.forEachAlive (this.check_collision, este); this.groups.special_fruits.forEachAlive (this.check_collision, este); this.groups.time_bombs.forEachAlive (this.check_collision, este); this.groups.clocks.forEachAlive (this.check_collision, este);}}; FruitNinja.LevelState.prototype.check_collision = función (objeto) { «utilizar estricta»; varobject_rectangle, línea 1, línea 2, línea 3, line4, intersección; // crear un rectángulo para el objeto bodyobject_rectangle = newPhaser.Rectangle (object.body.x, object.body.y, object.body.width, object.body.height); // cheque por intersecciones con cada rectángulo edgeline1 = newPhaser.Line (object_rectangle.left, object_rectangle.bottom, object_rectangle.left, object_rectangle.top); line2 = newPhaser.Line (object_rectangle.left, object_rectangle.top, object_rectangle.right, object_rectangle.top); línea3 = newPhaser.Line (object_rectangle.right, object_rectangle.top, object_rectangle.right, object_rectangle.bottom); line4 = newPhaser.Line (object_rectangle .RIGHT, object_rectangle.bottom, object_rectangle.left, object_rectangle.bottom); intersección = this.swipe.intersects (línea 1) || this.swipe.intersects (line2) || this.swipe.intersects (línea 3) || esto. swipe.intersects (4 en Línea), si (intersección) {// si no se encuentra una intersección, cortar la objectobject.cut ();}}; FruitNinja.LevelState.prototype.init_hud = función () { «utilizar estricta»; varscore_position, score_style, la puntuación; // crear prefabscore_position puntuación = newPhaser.Point (20,20); score_style = {font: «48px Shojumaru», relleno: «# fff»}; puntuación = newFruitNinja.Score (esto, «puntuación», score_position , {text: «Fruits:», el estilo: score_style, grupo: «HUD»});}; FruitNinja.LevelState.prototype.game_over = function () { «utilizar estricta»; vargame_over_panel, game_over_position, game_over_bitmap, panel_text_style; // si la puntuación actual es superior a la puntuación más alta, actualizar ITIF (localStorage [this.highest_score] || this.score> localStorage [this.highest_score]) {localStorage [this.highest_score] = this.score;} // crear un mapa de bits no mostrar el juego sobre panelgame_over_position = newPhas er.Point (0, this.game.world.height); game_over_bitmap = this.add.bitmapData (this.game.world.width, this.game.world.height); game_over_bitmap.ctx.fillStyle = «# 000» ; game_over_bitmap.ctx.fillRect (0,0, this.game.world.width, this.game.world.height); panel_text_style = {game_over: {font: «32px Shojumaru», relleno: «# FFF»}, current_score : {font: «20px Shojumaru», relleno: «# FFF»}, highest_score: {font: «18px Shojumaru», relleno: «# FFF»}}; // crear el juego más panelgame_over_panel = newFruitNinja.GameOverPanel (esto, «game_over_panel», game_over_position, {textura: game_over_bitmap, grupo: «HUD», text_style: panel_text_style, animation_time: 500}); this.groups.hud.add (game_over_panel);}; FruitNinja.LevelState.prototype.restart_level = function ( ) { «uso estricto»; this.game.state.restart (verdadero, falso, this.level_data);};

          Ahora, podemos escribir el código para ClassicState, lo que representa el modo de juego que ya teníamos. Dado que la mayor parte de su lógica ya está en LevelState y JSONLevelState, sólo tenemos que configurar el nombre de más alto puntaje y sobrescribir el método “init_hud” para incluir vidas jugador, como se muestra a continuación.
          var Fruit Ninja = Fruit Ninja || {}; FruitNinja.ClassicState = function () { «utilizar estricta»; FruitNinja.LevelState.call (this); this.prefab_classes = { «fruit_spawner»: FruitNinja.FruitSpawner.prototype.constructor, «bomb_spawner»: FruitNinja.BombSpawner.prototype.constructor, «special_fruit_spawner»: FruitNinja.SpecialFruitSpawner.prototype.constructor, «fondo»: FruitNinja.Prefab.prototype .constructor};}; FruitNinja.ClassicState.prototype = Object.create (FruitNinja.LevelState.prototype); FruitNinja.ClassicState.prototype.constructor = FruitNinja.ClassicState; FruitNinja.ClassicState.prototype.init = function (level_data) { «uso estricto»; FruitNinja.LevelState.prototype.init.call (esto, level_data); this.lives = 3; this.highest_score = «classic_score»;}; FruitNinja.ClassicState.prototype.init_hud = function () { «utilizar estricta»; FruitNinja.LevelState.prototype.init_hud.call (this); lives_position var, vidas; // crear vidas prefabricada lives_position = new Phaser.Point (0,75 * this.game.world.width, 20); vidas = new FruitNinja.Lives (Esto, «vidas», lives_position, {textura: «sword_image», grupo: «HUD», «vida»: 3, «lives_spacing»: 50});}; 12345678910111213141516171819202122232425262728293031323334varFruitNinja = Fruit Ninja || { }; FruitNinja.ClassicState = function () { «utilizar estricta»; FruitNinja.LevelState.call (this); this.prefab_classes = { «fruit_spawner»: FruitNinja.FruitSpawner.prototype.constructor, «bomb_spawner»: FruitNinja.BombSpawner.prototype .constructor, «special_fruit_spawner»: FruitNinja.SpecialFruitSpawner.prototype.constructor, «fondo»: FruitNinja.Prefab.prototype.constructor};}; FruitNinja.ClassicState.prototype = Object.create (FruitNinja.LevelState.prototype); FruitNinja.ClassicState .prototype.constructor = FruitNinja.ClassicState; FruitNinja.ClassicState.prototype.init = function (level_data) { «utilizar estricta»; FruitNinja.LevelState.prototype.init.call (esto, level_data); this.lives = 3; esto. highest_score = «classic_score»;}; FruitNinja.ClassicState.prototype.init_hud = function () { «utilizar estricta»; FruitNinja.LevelStat e.prototype.init_hud.call (this); varlives_position, vidas; // crear vidas prefablives_position = newPhaser.Point (0,75 * this.game.world.width, 20); vive = newFruitNinja.Lives (esto, «vidas», lives_position, {textura: «sword_image», grupo: «HUD», «vida»: 3, «lives_spacing»: 50});};

          te dejaré el código TimeAttackState para cuando vamos a utilizarlo .

          Custom fuente

          Vamos a añadir una fuente personalizada para mostrar todo el contenido de texto en nuestro juego, como el título, los elementos de menú, y el HUD. Puede descargar la fuente que vamos a utilizar aquí o con el código fuente. Para añadirlo al juego, sólo tiene que añadir una fuente cara en su archivo index.html. Sin embargo, podría no funcionar para todos los navegadores, de acuerdo con algunos informes en los foros de Phaser. Para evitar esto, se puede añadir un estilo para cargar la fuente personalizada y un objeto div en su archivo index.html para forzar al navegador a cargar la fuente.

          El index.html con ambos métodos se muestra a continuación. Observe que hemos cambiado la propiedad de “izquierda” del estilo .fontPreload ser -100px, por lo que el objeto div no será visible. Después de hacer eso, sólo tiene que utilizar el nombre de familia de fuentes (Shojumaru) en la propiedad de estilo de nuestras casas prefabricadas de texto.
          Aprender el desarrollo del juego en ZENVA.com </ title> </p> <style> body {padding: 0px; margen: 0px; background-color: negro; } @ Font-face {font-family: 'Shojumaru'; src: url ( 'activos / fonts / shojumaru.ttf'); .FontPreload} {font-family: Shojumaru; position: absolute; la izquierda: -100px; } </ Style> </ head> <body> </p> <div class = "fontPreload">. </ Div> <script type = "text / javascript" src = "js / phaser.js"> </ script> <script src = "js / estados / BootState.js"> </ script> <script src = "js / estados / LoadingState.js"> </ script> <script src = "js / estados / JSONLevelState.js"> </ script> <script src = "js / estados / TitleState.js"> </ script> <script src = "js / estados / LevelState.js"> </ script> <script src = "js / estados / ClassicState.js "> </ script> <script src =" js / estados / TimeAttackState.js "> </ script> <script src =" / js / prefabs Prefab.js "> </ script> <script src =" js / casas prefabricadas /TextPrefab.js "> </ script> <script src =" js / prefabs / reproductores / Spawner.js "> </ script> <script src =" js / prefabs / reproductores / FruitSpawner.js "> </ script> <script src = "js / prefabs / reproductores / BombSpawner.js"> </ script> <script src = "js / prefabs / reproductores / SpecialFruitSpawner.js"> </ script> <script src = "js / prefabs / reproductores /TimeBombSpawner.js "> </ script> <script src =" js / prefabs / reproductores / ClockSpawner.js "> </ script> <script src =" js / prefabs / Cuttables / Cuttable.js "> </ script> <script src = "js / pr efabs / Cuttables / Fruit.js "> </ script> <script src =" js / prefabs / Cuttables / Bomb.js "> </ script> <script src =" js / prefabs / Cuttables / SpecialFruit.js "> < / script> <script src = "js / prefabs / Cuttables / TimeBomb.js"> </ script> <script src = "js / prefabs / Cuttables / Clock.js"> </ script> <script src = "js / casas prefabricadas / Cuttables / Cut.js "> </ script> <script src =" js / casas prefabricadas / HUD / Score.js "> </ script> <script src =" js / casas prefabricadas / HUD / Lives.js "> < / script> <script src = "js / casas prefabricadas / HUD / RemainingTime.js"> </ script> <script src = "js / casas prefabricadas / HUD / GameOverPanel.js"> </ script> <script src = "/ js casas prefabricadas / HUD / Menu.js "> </ script> <script src =" js / casas prefabricadas / HUD / MenuItem.js "> </ script> <script src =" js / casas prefabricadas / HUD / StartGameItem.js "> < / script> <script type = "/ javascript texto" src = "js / main.js"> </ script> </ body> </ html> 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 <! DOCTYPE html> <html> <head> <meta charset = "UTF-8" /> <meta name = "viewport" content = "width = dispositivo de ancho, inicial escala = 1, max imo escala = 1, a escala mínima = 1, escalable user = no "/> <title> Aprender el desarrollo del juego en ZENVA.com </ title> </p> <style> body {padding: 0px; margen: 0px; background-color : negro;} @ font-face {font-family: 'Shojumaru'; src: url ( 'activos / fonts / shojumaru.ttf');} fontPreload {font-family: Shojumaru; posición:. absoluta; dejaron: -100px ;} </ style> </ head> <body> </p> <div class = "fontPreload"> </ div> <script type = "text / javascript" src = "js / phaser.js"> </ script> <. script src = "js / estados / BootState.js"> </ script> <script src = "js / estados / LoadingState.js"> </ script> <script src = "js / estados / JSONLevelState.js"> < / script> <script src = "js / estados / TitleState.js"> </ script> <script src = "js / estados / LevelState.js"> </ script> <script src = "js / estados / ClassicState. js "> </ script> <script src =" js / estados / TimeAttackState.js "> </ script> <script src =" js / casas prefabricadas / Prefab.js "> </ script> <script src =" js / prefabs / TextPrefab.js "> </ script> <script src =" js / prefabs / reproductores / Spawner.js "> </ script> <script src =" js / prefabs / reproductores / FruitSpawner.js "> </ script > <script src = "js / casas prefabricadas / reproductores / BombSpaw ner.js "> </ script> <script src =" js / prefabs / reproductores / SpecialFruitSpawner.js "> </ script> <script src =" js / prefabs / reproductores / TimeBombSpawner.js "> </ script> < script src = "js / prefabs / reproductores / ClockSpawner.js"> </ script> <script src = "js / prefabs / Cuttables / Cuttable.js"> </ script> <script src = "js / prefabs / Cuttables / Fruit.js "> </ script> <script src =" js / casas prefabricadas / Cuttables / Bomb.js "> </ script> <script src =" js / casas prefabricadas / Cuttables / SpecialFruit.js "> </ script> < script src = "js / prefabs / Cuttables / TimeBomb.js"> </ script> <script src = "js / prefabs / Cuttables / Clock.js"> </ script> <script src = "js / prefabs / Cuttables / Cut.js "> </ script> <script src =" js / casas prefabricadas / HUD / Score.js "> </ script> <script src =" js / casas prefabricadas / HUD / Lives.js "> </ script> < script src = "js / casas prefabricadas / HUD / RemainingTime.js"> </ script> <script src = "js / casas prefabricadas / HUD / GameOverPanel.js"> </ script> <script src = "js / casas prefabricadas / HUD / Menu.js "> </ script> <script src =" js / casas prefabricadas / HUD / MenuItem.js "> </ script> <script src =" js / casas prefabricadas / HUD / StartGameItem.js "> </ script> < script type = "text / javascript" src = "js / main.js"> </ script> </ bo dy> </ html> </p> <h2> pantalla de título </ h2><br /> <P> La pantalla de título tendrá el título del juego y un menú con las opciones del modo de juego. Para hacer eso, tenemos que crear MenuItem y Menú casas prefabricadas. El Menultem será una casa prefabricada de texto que muestra un modo de juego. Cuando la selección del menú es más de un elemento, que jugará un animación de interpolación para cambiar la escala elemento hacia arriba y hacia abajo. Cuando el jugador selecciona un tema, queremos que se ejecute alguna acción, llamando al método “seleccionar”. Por defecto, este método no hace nada, por lo que vamos a escribir nuevas casas prefabricadas que se extenderán Menultem y puede sobrescribir la este método. </ P><br /> <P> El código prefabricada MenuItem se muestra a continuación. En el constructor, se crea una animación de interpolación para el objeto de escala. A continuación, añadimos dos niños a este Tween, llamando a su “a” método dos veces, una para aumentar la escala y otro para disminuirlo. Por último, utilizamos el método “repeatAll” para mantener la interpolación repetir después de que todos los niños se ejecutan. Por último, en el método “selection_over” empezamos la interpolación, mientras que en el método “selection_out” lo detenemos. </ P><br /> var Fruit Ninja = Fruit Ninja || {}; FruitNinja.MenuItem = function (game_state, nombre, posición, propiedades) { "utilizar estricta"; FruitNinja.TextPrefab.call (esto, game_state, nombre, posición, propiedades); this.anchor.setTo (0,5); this.on_selection_animation = this.game_state.game.add.tween (this.scale); this.on_selection_animation.to ({x: 1,5 * this.scale.x, y: 1,5 * this.scale.y}, 500); this.on_selection_animation.to ({x: this.scale.x, y: this.scale.y}, 500); this.on_selection_animation.repeatAll (-1);}; FruitNinja.MenuItem.prototype = Object.create (FruitNinja.TextPrefab.prototype); FruitNinja.MenuItem.prototype.constructor = FruitNinja.MenuItem; FruitNinja.MenuItem.prototype.selection_over = function () { "utilizar estricta"; si (this.on_selection_animation.isPaused) {this.on_selection_animation.resume (); } Else {this.on_selection_animation.start (); }}; FruitNinja.MenuItem.prototype.selection_out = function () { "utilizar estricta"; this.on_selection_animation.pause ();}; FruitNinja.MenuItem.prototype.select = function () { "utilizar estricta"; // el elemento predeterminado no hace nada}; 1234567891011121314151617181920212223242526272829303132333435varFruitNinja = Fruit Ninja || {}; FruitNinja.MenuItem = function (game_state, nombre, posición, propiedades) { "use strict"; FruitNinja.TextPrefab.call (esto, game_state, nombre, cargo , propiedades); this.anchor.setTo (0,5); this.on_selection_animation = this.game_state.game.add.tween (this.scale); this.on_selection_animation.to ({x: 1,5 * this.scale.x, y : 1,5 * this.scale.y}, 500); this.on_selection_animation.to ({x: this.scale.x, Y: this.scale.y}, 500); this.on_selection_animation.repeatAll (-1); }; FruitNinja.MenuItem.prototype = Object.create (FruitNinja.TextPrefab.prototype); FruitNinja.MenuItem.prototype.constructor = FruitNinja.MenuItem; FruitNinja.MenuItem.prototype.selection_over = function () { "utilizar estricta", si ( this.on_selection_animation.isPaused) {this.on_selection_animation.resume ();} else {this.on_selection_animation.start ();}}; FruitNinja.MenuItem.prototype.selection_out = function () { "utilizar estricta"; this.on_selection_animation. pausa ();}; FruitNinj a.MenuItem.prototype.select = function () { "use strict"; // el elemento predeterminado no hace nada}; </p> <p> Ahora, vamos a escribir el código prefabricada menú, el cual tendrá una lista de elementos y navegará a través ellos. El Código de menú se muestra a continuación. En el constructor, los elementos de menú se reciben desde el parámetro de propiedades y el primero es en virtud de selección. En el método de “actualización”, comprobamos para las direccionales para navegar a través de los artículos y la barra espaciadora para seleccionar el elemento actual. Tenga en cuenta que, cuando se navega a través de los artículos, hay que quitar la selección del elemento actual y el cambio a la nueva. Cuando se pulsa la barra espaciadora, sólo tenemos que seleccionar el elemento actual. </ P><br /> var Fruit Ninja = Fruit Ninja || {}; FruitNinja.Menu = function (game_state, nombre, posición, propiedades) { "utilizar estricta"; live_index var, la vida; FruitNinja.Prefab.call (esto, game_state, nombre, posición, propiedades); = This.visible FALSE; this.menu_items = properties.menu_items; this.current_item_index = 0; this.menu_items [0] .selection_over (); this.cursor_keys = this.game_state.game.input.keyboard.createCursorKeys ();}; FruitNinja.Menu.prototype = Object.create (FruitNinja.Prefab.prototype); FruitNinja.Menu.prototype.constructor = FruitNinja.Menu; Fruit Ninja .Menu.prototype.update = function () { "utilizar estricta"; si (this.cursor_keys.up.isDown && this.current_item_index> 0) {// navegar a this.menu_items de artículos anteriores [this.current_item_index] .selection_out (); this.current_item_index - = 1; this.menu_items [this.current_item_index] .selection_over (); } Else if (this.cursor_keys.down.isDown && this.current_item_index <this.menu_items.length - 1) {// navegar a próximos this.menu_items item [this.current_item_index] .selection_out (); this.current_item_index + = 1; this.menu_items [this.current_item_index] .selection_over (); } If (this.game_state.game.input.keyboard.isDown (Phaser.Keyboard.SPACEBAR)) {this.menu_items [this.current_item_index] .select (); }}; 12345678910111213141516171819202122232425262728293031323334353637varFruitNinja = Fruit Ninja || {}; FruitNinja.Menu = función (game_state, nombre, posición, propiedades) { "uso estricto"; varlive_index, la vida; FruitNinja.Prefab.call (Esto, game_state, nombre, posición, propiedades ); this.visible = false; this.menu_items = properties.menu_items; this.current_item_index = 0; this.menu_items [0] .selection_over (); this.cursor_keys = this.game_state.game.input.keyboard.createCursorKeys () ;}; FruitNinja.Menu.prototype = Object.create (FruitNinja.Prefab.prototype); FruitNinja.Menu.prototype.constructor = FruitNinja.Menu; FruitNinja.Menu.prototype.update = function () { "utilizar estricta", si (this.cursor_keys.up.isDown && this.current_item_index> 0) {// navegar a this.menu_items anteriores item [this.current_item_index] .selection_out (); this.current_item_index- = 1; this.menu_items [this.current_item_index]. selection_over ();} elseif (this.cursor_keys.down.isDown && this.current_item_index <this.menu_items.length - 1) {// navegar a próximos this.menu_items elemento [t his.current_item_index] .selection_out (); this.current_item_index + = 1; this.menu_items [this.current_item_index] .selection_over ();} if (this.game_state.game.input.keyboard.isDown (Phaser.Keyboard.SPACEBAR)) {this.menu_items [this.current_item_index] .select ();}}; <p> Finalmente, podemos crear el TitleState utilizando el menú y casas prefabricadas MenuItem. Los elementos del menú se cargan desde el archivo JSON (que se puede comprobar en el código fuente), por lo que sólo tenemos que añadir el título del juego y el menú en el método de “crear”. El título es simplemente una casa prefabricada de texto. Para pasar los elementos de menú al menú iteramos a través del grupo “menu_items”, guardándolos en una matriz, que se pasará al menú. </ P><br /> var Fruit Ninja = Fruit Ninja || {}; FruitNinja.TitleState = function () { "utilizar estricta"; FruitNinja.JSONLevelState.call (this); this.prefab_classes = { "start_game_item": FruitNinja.StartGameItem.prototype.constructor, "fondo": FruitNinja.Prefab.prototype.constructor};}; FruitNinja.TitleState.prototype = Object.create (FruitNinja.JSONLevelState.prototype); Fruit Ninja .TitleState.prototype.constructor = FruitNinja.TitleState; FruitNinja.TitleState.prototype.create = function () { "utilizar estricta"; var title_position, title_style, título, menu_position, menu_items, menu_properties, menú; FruitNinja.JSONLevelState.prototype.create.call (this); // añadiendo título title_position = new Phaser.Point (0,5 * this.game.world.width, 0,3 * this.game.world.height); title_style = {font: "72px Shojumaru", relleno: "#FFF"}; title = nueva FruitNinja.TextPrefab (esto, "título", title_position, {texto: "Fruit Ninja", el estilo: title_style, grupo: "HUD"}); title.anchor.setTo (0,5); // añadiendo menú menu_position = new Phaser.Point (0, 0); menu_items = []; this.groups.menu_items.forEach (function (menu_item) {menu_items.push (menu_item);}, this); menu_properties = {textura: "", grupo: "fondo", menu_items: menu_items}; menu = nueva FruitNinja.Menu (esto "menú", menu_position, menu_properties);}; 1234567891011121314151617181920212223242526272829303132333435varFruitNinja = Fruit Ninja || {}; FruitNinja.TitleState = function () { "use strict"; FruitNinja.JSONLevelState.call (this); this.prefab_classes={"start_game_item":FruitNinja.StartGameItem.prototype.constructor,"background":FruitNinja.Prefab.prototype.constructor};};FruitNinja.TitleState.prototype=Object.create(FruitNinja.JSONLevelState.prototype);FruitNinja .TitleState.prototype.constructor=FruitNinja.TitleState;FruitNinja.TitleState.prototype.create=function(){"use strict";vartitle_position,title_style,title,menu_position,menu_items,menu_properties,menu;FruitNinja.JSONLevelState.prototype.create. call(this);// adding titletitle_position=newPhaser.Point(0.5*this.game.world.width,0.3*this.game.world.height);title_style={font:"72px Shojumaru",fill:"#FFF "};title=newFruitNinja.TextPrefab(this,"title",title_position,{text:"Fruit Ninja",style:title_style,group:"hud"});tit le.anchor.setTo(0.5);// adding menumenu_position=newPhaser.Point(0,0);menu_items=[];this.groups.menu_items.forEach(function(menu_item){menu_items.push(menu_item);},this);menu_properties={texture:"",group:"background",menu_items:menu_items};menu=newFruitNinja.Menu(this,"menu",menu_position,menu_properties);};</p> <p>You can already run the game with the title screen, to see it working.</p> <p><img src="http://fymm-rpg.net/wp-content/uploads/placeholder-300x151.png" alt="title" /></p> <h2>Time attack state</h2> <p>Since we already have most of the game logic in the LevelState, the TimeAttackState is easy to implement, as shown below. Notice that, besides setting the highest score variable, we only have to add the remaining time to the hud, which is updated in the “update” method.</p> <p>var FruitNinja = FruitNinja || {};FruitNinja.TimeAttackState = function () { "use strict"; FruitNinja.LevelState.call(this); this.prefab_classes = { "fruit_spawner": FruitNinja.FruitSpawner.prototype.constructor, "time_bomb_spawner": FruitNinja.TimeBombSpawner.prototype.constructor, "clock_spawner": FruitNinja.ClockSpawner.prototype.constructor, "special_fruit_spawner": FruitNinja.SpecialFruitSpawner.prototype.constructor, "background": FruitNinja.Prefab.prototype.constructor };};FruitNinja.TimeAttackState.prototype = Object.create(FruitNinja.LevelState.prototype);FruitNinja.TimeAttackState.prototype.constructor = FruitNinja.TimeAttackState;FruitNinja.TimeAttackState.prototype.init = function (level_data) { "use strict"; FruitNinja.LevelState.prototype.init.call(this, level_data); this.remaining_time = Phaser.Timer.SECOND * 60; this.highest_score = "time_attack_score";};FruitNinja.TimeAttackState.prototype.update = function () { "use strict"; if (this.remaining_time > 0) { this.remaining_time -= this.game.time.elapsed; if (this.remaining_time <= 0) { this.game_over(); this.remaining_time = 0; } }};FruitNinja.TimeAttackState.prototype.init_hud = function () { "use strict"; FruitNinja.LevelState.prototype.init_hud.call(this); var remaining_time_position, remaining_time_style, remaining_time; // show remaining time remaining_time_position = new Phaser.Point(0.5 * this.game.world.width, 20); remaining_time_style = {font: "48px Shojumaru", fill: "#fff"}; remaining_time = new FruitNinja.RemainingTime(this, "remaining_time", remaining_time_position, {text: "Remaining time: ", style: remaining_time_style, group: "hud"});};1234567891011121314151617181920212223242526272829303132333435363738394041424344454647varFruitNinja=FruitNinja||{};FruitNinja.TimeAttackState=function(){"use strict";FruitNinja.LevelState.call(this);this.prefab_classes={"fruit_spawner":FruitNinja.FruitSpawner.prototype.constructor,"time_bomb_spawner":FruitNinja.TimeBombSpawner.prototype.constructor,"clock_spawner":FruitNinja.ClockSpawner.prototype.constructor,"special_fruit_spawner":FruitNinja.SpecialFruitSpawner.prototype.constructor,"background":FruitNinja.Prefab.prototype.constructor};};FruitNinja.TimeAttackState.prototype=Object.create(FruitNinja.LevelState.prototype);FruitNinja.TimeAttackState.prototype.constructor=FruitNinja.TimeAttackState;FruitNinja.TimeAttackState.prototype.init=function(level_data){"use strict";FruitNinja.LevelState.prototype.init.call(this,level_data);this.remaining_time=Phaser.Timer.SECOND*60;this.highest_score="time_attack_score";};FruitNinja.TimeAttackState.prototype.update=function(){"use strict";if(this.remaining_time>0){this.remaining_time-=this.game.time.elapsed;if(this.remaining_time<=0){this.game_over();this.remaining_time=0;}}};FruitNinja.TimeAttackState.prototype.init_hud=function(){"use strict";FruitNinja.LevelState.prototype.init_hud.call(this);varremaining_time_position,remaining_time_style,remaining_time;// show remaining timeremaining_time_position=newPhaser.Point(0.5*this.game.world.width,20);remaining_time_style={font:"48px Shojumaru",fill:"#fff"};remaining_time=newFruitNinja.RemainingTime(this,"remaining_time",remaining_time_position,{text:"Remaining time: ",style:remaining_time_style,group:"hud"});}; <p>To show the remaining time we create a RemainingTime prefab, which is simply a text prefab that shows the remaining time value. To update it, we use “this.game.time.elapsed”, which contains the elapsed time since the last update, in milliseconds.</p> <p>var FruitNinja = FruitNinja || {};FruitNinja.RemainingTime = function (game_state, name, position, properties) { "use strict"; FruitNinja.TextPrefab.call(this, game_state, name, position, properties);};FruitNinja.RemainingTime.prototype = Object.create(FruitNinja.TextPrefab.prototype);FruitNinja.RemainingTime.prototype.constructor = FruitNinja.RemainingTime;FruitNinja.RemainingTime.prototype.update = function () { "use strict"; // update the text to show the remaining time in seconds this.text = "Remaining time: " + this.game_state.remaining_time / Phaser.Timer.SECOND;};123456789101112131415varFruitNinja=FruitNinja||{};FruitNinja.RemainingTime=function(game_state,name,position,properties){"use strict";FruitNinja.TextPrefab.call(this,game_state,name,position,properties);};FruitNinja.RemainingTime.prototype=Object.create(FruitNinja.TextPrefab.prototype);FruitNinja.RemainingTime.prototype.constructor=FruitNinja.RemainingTime;FruitNinja.RemainingTime.prototype.update=function(){"use strict";// update the text to show the remaining time in secondsthis.text="Remaining time: "+this.game_state.remaining_time/Phaser.Timer.SECOND;};</p> <p>You can already try playing the Time Attack mode with the regular prefabs and see if it’s working.</p> <p><img src="http://fymm-rpg.net/wp-content/uploads/time-attack-300x148.png" alt="time_attack" /></p> <h2>Clock and time bomb</h2> <p>Since we have our generic Cuttable and Spawner prefabs, adding the clock and the time bomb will be easily done as we did with the special fruit in the last tutorial.</p> <p>First, we will create the Clock and TimeBomb prefabs, which will extend Cuttable, as shown below. For each one, the only thing we have to do is change the “cut” method. In the Clock prefab, we increase the reamining time by 3 seconds, while in the TimeBomb we decrease it by 5 seconds.</p> <p>var FruitNinja = FruitNinja || {};FruitNinja.Clock = function (game_state, name, position, properties) { "use strict"; FruitNinja.Cuttable.call(this, game_state, name, position, properties); this.body.setSize(20, 20);};FruitNinja.Clock.prototype = Object.create(FruitNinja.Cuttable.prototype);FruitNinja.Clock.prototype.constructor = FruitNinja.Clock;FruitNinja.Clock.prototype.cut = function () { "use strict"; FruitNinja.Cuttable.prototype.cut.call(this); // if a time bomb is cut, increase the remaining time by 3 seconds this.game_state.remaining_time += Phaser.Timer.SECOND * 3; this.kill();};12345678910111213141516171819varFruitNinja=FruitNinja||{};FruitNinja.Clock=function(game_state,name,position,properties){"use strict";FruitNinja.Cuttable.call(this,game_state,name,position,properties);this.body.setSize(20,20);};FruitNinja.Clock.prototype=Object.create(FruitNinja.Cuttable.prototype);FruitNinja.Clock.prototype.constructor=FruitNinja.Clock;FruitNinja.Clock.prototype.cut=function(){"use strict";FruitNinja.Cuttable.prototype.cut.call(this);// if a time bomb is cut, increase the remaining time by 3 secondsthis.game_state.remaining_time+=Phaser.Timer.SECOND*3;this.kill();};var FruitNinja = FruitNinja || {};FruitNinja.TimeBomb = function (game_state, name, position, properties) { "use strict"; FruitNinja.Cuttable.call(this, game_state, name, position, properties); this.body.setSize(20, 20);};FruitNinja.TimeBomb.prototype = Object.create(FruitNinja.Cuttable.prototype);FruitNinja.TimeBomb.prototype.constructor = FruitNinja.TimeBomb;FruitNinja.TimeBomb.prototype.cut = function () { "use strict"; FruitNinja.Cuttable.prototype.cut.call(this); // if a time bomb is cut, decrease the remaining time by 5 seconds this.game_state.remaining_time -= Phaser.Timer.SECOND * 5; this.kill();};12345678910111213141516171819varFruitNinja=FruitNinja||{};FruitNinja.TimeBomb=function(game_state,name,position,properties){"use strict";FruitNinja.Cuttable.call(this,game_state,name,position,properties);this.body.setSize(20,20);};FruitNinja.TimeBomb.prototype=Object.create(FruitNinja.Cuttable.prototype);FruitNinja.TimeBomb.prototype.constructor=FruitNinja.TimeBomb;FruitNinja.TimeBomb.prototype.cut=function(){"use strict";FruitNinja.Cuttable.prototype.cut.call(this);// if a time bomb is cut, decrease the remaining time by 5 secondsthis.game_state.remaining_time-=Phaser.Timer.SECOND*5;this.kill();};</p> <p>Next, we will create the spawner for both prefabs. Here the only method we have to change is “create_object”, which will return a new Clock for the ClockSpawner and a new TimeBomb for the TimeBombSpawner.</p> <p>var FruitNinja = FruitNinja || {};FruitNinja.ClockSpawner = function (game_state, name, position, properties) { "use strict"; FruitNinja.Spawner.call(this, game_state, name, position, properties);};FruitNinja.ClockSpawner.prototype = Object.create(FruitNinja.Spawner.prototype);FruitNinja.ClockSpawner.prototype.constructor = FruitNinja.ClockSpawner;FruitNinja.ClockSpawner.prototype.create_object = function (name, position, velocity) { "use strict"; // return new time bomb console.log("spawning clock"); return new FruitNinja.Clock(this.game_state, name, position, {texture: "clock_image", group: "clocks", velocity: velocity});};12345678910111213141516varFruitNinja=FruitNinja||{};FruitNinja.ClockSpawner=function(game_state,name,position,properties){"use strict";FruitNinja.Spawner.call(this,game_state,name,position,properties);};FruitNinja.ClockSpawner.prototype=Object.create(FruitNinja.Spawner.prototype);FruitNinja.ClockSpawner.prototype.constructor=FruitNinja.ClockSpawner;FruitNinja.ClockSpawner.prototype.create_object=function(name,position,velocity){"use strict";// return new time bombconsole.log("spawning clock");returnnewFruitNinja.Clock(this.game_state,name,position,{texture:"clock_image",group:"clocks",velocity:velocity});};var FruitNinja = FruitNinja || {};FruitNinja.TimeBombSpawner = function (game_state, name, position, properties) { "use strict"; FruitNinja.Spawner.call(this, game_state, name, position, properties);};FruitNinja.TimeBombSpawner.prototype = Object.create(FruitNinja.Spawner.prototype);FruitNinja.TimeBombSpawner.prototype.constructor = FruitNinja.TimeBombSpawner;FruitNinja.TimeBombSpawner.prototype.create_object = function (name, position, velocity) { "use strict"; // return new time bomb return new FruitNinja.TimeBomb(this.game_state, name, position, {texture: "time_bomb_image", group: "time_bombs", velocity: velocity});};123456789101112131415varFruitNinja=FruitNinja||{};FruitNinja.TimeBombSpawner=function(game_state,name,position,properties){"use strict";FruitNinja.Spawner.call(this,game_state,name,position,properties);};FruitNinja.TimeBombSpawner.prototype=Object.create(FruitNinja.Spawner.prototype);FruitNinja.TimeBombSpawner.prototype.constructor=FruitNinja.TimeBombSpawner;FruitNinja.TimeBombSpawner.prototype.create_object=function(name,position,velocity){"use strict";// return new time bombreturnnewFruitNinja.TimeBomb(this.game_state,name,position,{texture:"time_bomb_image",group:"time_bombs",velocity:velocity});};</p> <p>Now, you can add the two new spawner in the Time Attack mode and try playing it.</p> <p><img src="http://fymm-rpg.net/wp-content/uploads/clock-300x149.png" alt="clock" /></p> <p><H2> Acabado del juego </ h2></p> <p><strong>And that concludes our Fruit Ninja game, tell me our opinion on this tutorial series and what games you would like to see next.</strong></p> <p><H3> Mensajes relacionados </ h3><br /> <img src="http://fymm-rpg.net/wp-content/uploads/banners2015-gameplatinum-150x150.jpg" alt="The Complete Mobile Game Development Course – Platinum Edition" /><img src="http://fymm-rpg.net/wp-content/uploads/placeholder-1362x684.png" alt="" /><img src="http://fymm-rpg.net/wp-content/uploads/placeholder-1362x684.png" alt="" /></p> </div><!-- .entry-content --> </div><!-- .post-inner --> <div class="section-inner"> </div><!-- .section-inner --> <div class="comments-wrapper section-inner"> <div id="respond" class="comment-respond"> <h2 id="reply-title" class="comment-reply-title">Deja una respuesta <small><a rel="nofollow" id="cancel-comment-reply-link" href="/206-2/#respond" style="display:none;">Cancelar la respuesta</a></small></h2><form action="http://fymm-rpg.net/wp-comments-post.php" method="post" id="commentform" class="section-inner thin max-percentage" novalidate><p class="comment-notes"><span id="email-notes">Tu dirección de correo electrónico no será publicada.</span> Los campos obligatorios están marcados con <span class="required">*</span></p><p class="comment-form-comment"><label for="comment">Comentario</label> <textarea id="comment" name="comment" cols="45" rows="8" maxlength="65525" required="required"></textarea></p><p class="comment-form-author"><label for="author">Nombre <span class="required">*</span></label> <input id="author" name="author" type="text" value="" size="30" maxlength="245" required='required' /></p> <p class="comment-form-email"><label for="email">Correo electrónico <span class="required">*</span></label> <input id="email" name="email" type="email" value="" size="30" maxlength="100" aria-describedby="email-notes" required='required' /></p> <p class="comment-form-url"><label for="url">Web</label> <input id="url" name="url" type="url" value="" size="30" maxlength="200" /></p> <p class="comment-form-cookies-consent"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes" /> <label for="wp-comment-cookies-consent">Guardar mi nombre, correo electrónico y web en este navegador para la próxima vez que comente.</label></p> <p class="form-submit"><input name="submit" type="submit" id="submit" class="submit" value="Publicar el comentario" /> <input type='hidden' name='comment_post_ID' value='206' id='comment_post_ID' /> <input type='hidden' name='comment_parent' id='comment_parent' value='0' /> </p></form> </div><!-- #respond --> </div><!-- .comments-wrapper --> </article><!-- .post --> </main><!-- #site-content --> <div class="footer-nav-widgets-wrapper header-footer-group"> <div class="footer-inner section-inner"> <aside class="footer-widgets-outer-wrapper" role="complementary"> <div class="footer-widgets-wrapper"> <div class="footer-widgets column-one grid-item"> <div class="widget widget_search"><div class="widget-content"><form role="search" method="get" class="search-form" action="http://fymm-rpg.net/"> <label for="search-form-2"> <span class="screen-reader-text">Buscar:</span> <input type="search" id="search-form-2" class="search-field" placeholder="Buscar …" value="" name="s" /> </label> <input type="submit" class="search-submit" value="Buscar" /> </form> </div></div> <div class="widget widget_recent_entries"><div class="widget-content"> <h2 class="widget-title subheading heading-size-3">Entradas recientes</h2> <ul> <li> <a href="http://fymm-rpg.net/2020/09/20/hola-mundo/">¡Hola, mundo!</a> </li> </ul> </div></div><div class="widget widget_recent_comments"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Comentarios recientes</h2><ul id="recentcomments"><li class="recentcomments"><span class="comment-author-link"><a href='https://wordpress.org/' rel='external nofollow ugc' class='url'>Un comentarista de WordPress</a></span> en <a href="http://fymm-rpg.net/2020/09/20/hola-mundo/#comment-1">¡Hola, mundo!</a></li></ul></div></div> </div> <div class="footer-widgets column-two grid-item"> <div class="widget widget_archive"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Archivos</h2> <ul> <li><a href='http://fymm-rpg.net/2020/09/'>septiembre 2020</a></li> </ul> </div></div><div class="widget widget_categories"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Categorías</h2> <ul> <li class="cat-item cat-item-1"><a href="http://fymm-rpg.net/category/sin-categoria/">Sin categoría</a> </li> </ul> </div></div><div class="widget widget_meta"><div class="widget-content"><h2 class="widget-title subheading heading-size-3">Meta</h2> <ul> <li><a href="http://fymm-rpg.net/wp-login.php">Acceder</a></li> <li><a href="http://fymm-rpg.net/feed/">Feed de entradas</a></li> <li><a href="http://fymm-rpg.net/comments/feed/">Feed de comentarios</a></li> <li><a href="https://es.wordpress.org/">WordPress.org</a></li> </ul> </div></div> </div> </div><!-- .footer-widgets-wrapper --> </aside><!-- .footer-widgets-outer-wrapper --> </div><!-- .footer-inner --> </div><!-- .footer-nav-widgets-wrapper --> <footer id="site-footer" role="contentinfo" class="header-footer-group"> <div class="section-inner"> <div class="footer-credits"> <p class="footer-copyright">© 2020 <a href="http://fymm-rpg.net/">Rpg Dev</a> </p><!-- .footer-copyright --> <p class="powered-by-wordpress"> <a href="https://es.wordpress.org/"> Funciona con WordPress </a> </p><!-- .powered-by-wordpress --> </div><!-- .footer-credits --> <a class="to-the-top" href="#site-header"> <span class="to-the-top-long"> Ir arriba <span class="arrow" aria-hidden="true">↑</span> </span><!-- .to-the-top-long --> <span class="to-the-top-short"> Subir <span class="arrow" aria-hidden="true">↑</span> </span><!-- .to-the-top-short --> </a><!-- .to-the-top --> </div><!-- .section-inner --> </footer><!-- #site-footer --> <script src='http://fymm-rpg.net/wp-includes/js/comment-reply.min.js?ver=5.4.2'></script> <script src='http://fymm-rpg.net/wp-includes/js/wp-embed.min.js?ver=5.4.2'></script> <script> /(trident|msie)/i.test(navigator.userAgent)&&document.getElementById&&window.addEventListener&&window.addEventListener("hashchange",function(){var t,e=location.hash.substring(1);/^[A-z0-9_-]+$/.test(e)&&(t=document.getElementById(e))&&(/^(?:a|select|input|button|textarea)$/i.test(t.tagName)||(t.tabIndex=-1),t.focus())},!1); </script> </body> </html>