Desarrollo de Juegos 2D en HTML5: Implementación de comportamientos de sprites

Cómo asignar comportamientos a los personajes de Snail Bait

En esta serie, el experto en HTML5 David Geary muestra cómo implementar un videojuego 2D en HTML5 paso a paso. En esta parte, aprenderás a implementar la esencia de cualquier videojuego: los comportamientos de sprites.

David Geary, Autor y conferencista, Clarity Training, Inc.

David GearyEl autor de Core HTML5 Canvas, David Geary, es también el cofundador del Grupo de usuarios de HTML5 de Denver y autor de ocho libros sobre Java, que incluyen los best sellers Swing y JavaServer Faces. David es disertante frecuente en conferencias, entre ellas JavaOne, Devoxx, Strange Loop, NDC y OSCON, y ganó el premio JavaOne Rock Star tres veces. Escribió la serie de artículosJSF 2 fu y GWT fu para developerWorks. Puede seguir a David en Twitter en @davidgeary.



20-05-2013

Las grandes historias tienen grandes personajes. Al igual que en los libros y las películas, los videojuegos también necesitan personajes con comportamientos interesantes. Por ejemplo, el protagonista de Braid— la plataforma de juego más vendida de todos los tiempos— puede manipular el tiempo. Ese ingenioso comportamiento diferenció al juego del resto de los juegos de la época.

Los comportamientos son el alma de cualquier videojuego y añadir comportamientos a los sprites inertes de Snail Bait que se implementaron en elartículo anterior hace que el juego inmediatamente sea más interesante, como se muestra en la Figura 1:

Figura 1. Estado de Snail Bait al final de este artículo
Screen shot of Snail Bait state at the end of this article

Retomando la sección Objetos Sprite del artículo anterior, vemos que los sprites de Snail Bait no implementan sus propias actividades como correr, saltar o explotar. En cambio, dependen de otros objetos — conocidos como comportamientos — para controlar sus acciones.

La Figura 1 muestra al caracol disparando una bomba. Otros comportamientos que se pueden observar en la imagen estática de la Figura 1 son:

  • La corredora corre
  • Los botones permiten el desplazamiento hacia adelante y hacia atrás en las plataformas
  • Los rubíes y zafiros brillan

La Tabla 1 resume esos comportamientos:

Tabla 1. Comportamientos que se describen en este artículo
SpritesComportamientoDescripción
Botones, caracoles paceBehavior Permite el desplazamiento hacia adelante y hacia atrás en una plataforma
Corredora runBehavior Reproduce el ciclo de imágenes de la corredora creando la ilusión de que está corriendo
Caracol snailShootBehavior Dispara una bomba desde la boca del caracol
Caracol cycleBehavior Reproduce el ciclo de imágenes del caracol
Bomba de caracol snailBombMoveBehavior Mueve la bomba horizontalmente hacia la izquierda mientras está visible en el canvas

Manipulación del tiempo

En Braid, el protagonista Tim manipula el tiempo. Sin embargo, en todos los videojuegos se manipula el tiempo. En este artículo, conocerá el trasfondo del flujo de tiempo a través de los comportamientos. Y en los próximos dos artículos de esta serie, mostraré cómo doblegar el tiempo para implementar movimientos no lineales, que constituye la base de los movimientos realistas como correr y saltar.

Los comportamientos enumerados en la Tabla 1 representan menos de la mitad de los comportamientos del videojuego — como se puede observar en la tabla de sprites y comportamientos de Snail Bait en el primer artículo de esta serie. Además, son los comportamientos más básicos de los sprites; correr, por ejemplo, es bastante más complejo (como verá en los próximos artículos). No obstante, este artículo contiene mucha información sobre la implementación de los comportamientos más simples, que incluye:

  • Cómo implementar comportamientos y asignarlos a los sprites
  • Cómo reproducir un ciclo de imágenes de un sprite
  • Cómo crear comportamientos ligeros para ahorrar uso de la memoria
  • Cómo combinar comportamientos
  • Cómo utilizar los comportamientos para disparar proyectiles

Fundamentos de los comportamientos

Comportamientos de Replica Island

La idea de comportamientos proviene de un juego de código abierto Android llamado Replica Island. Muchos de los gráficos de Snail Bait también vienen de Replica Island. Consulte Recursos y encuentre enlaces al juego y a una publicación en un blog donde su creador habla sobre los comportamientos.

Cualquier objeto puede ser un comportamiento, siempre y cuando contenga un método execute() . Ese método incluye tres argumentos: un sprite, el tiempo y la velocidad de fotogramas para la animación del juego. El método execute() de un comportamiento modifica el estado del sprite según el tiempo y la velocidad de fotogramas de la animación.

Los comportamientos son eficientes porque:

  • Separan los sprites del modo en que se comportan.
  • Permiten cambiar los comportamientos de sprites en tiempo de ejecución.
  • Permiten implementar comportamientos que funcionan con cualquier sprite.
  • Se pueden utilizar comportamientos sin estado como objetos ligeros.

Antes de abordar los detalles de la implementación de los comportamientos enumerados en la Tabla 1, haré una descripción general de los comportamientos en un nivel más profundo — cómo implementarlos y asociarlos a los sprites — usando como referencia los comportamientos colectivos de la corredora.


Comportamientos de la corredora

La corredora de Snail Bait posee cuatro comportamientos, enumerados en la Tabla 2:

Tabla 2. Comportamientos de la corredora
ComportamientoDescripción
runBehavior Reproduce el ciclo a través de las celdas de la hoja de sprites de la corredora para hacer que parezca que está corriendo
jumpBehavior Controla todos los aspectos de los saltos: ascenso, descenso y caída
fallBehavior Controla el movimiento vertical de la corredora cuando se cae
runnerCollideBehavior Detecta las colisiones entre la corredora y otros sprites, y reacciona frente a ellas

Especifico los comportamientos de la corredora con un array de objetos que le paso al constructor de sprites , como se muestra en el Listado 1:

Listado 1. Cómo crear a la corredora de Snail Bait
var SnailBait = function () {
   ...

   this.runner = new Sprite('runner',              // Type
                            this.runnerArtist,    //  Artist
                            [this.runBehavior,  //  Behaviors
                          this.jumpBehavior,
                          this.fallBehavior,
                          this.runnerCollideBehavior

                           ]);
};

En el Listado 2, se muestran los comportamientos de la corredora sin los detalles de implementación:

Listado 2. Objetos de comportamiento de la corredora
var SnailBait = function () {
   ...

   this.runBehavior = {
      execute: function(sprite, time, fps) { // sprite is the runner
         ...
      }
   };
   this.jumpBehavior = {
      execute: function(sprite, time, fps) { // sprite is the runner
         ...
      }
   };
   this.fallBehavior = {
      execute: function(sprite, time, fps) { // sprite is the runner
         ...
      }
   };
   this.runnerCollideBehavior = {
      execute: function(sprite, time, fps) { // sprite is the runner
         ...
      }
   };
};

En todos los fotogramas de animación, Snail Bait itera con su array de sprites, invocando el método update() de cada sprite, que se muestra en el Listado 3:

Listado 3. Cómo ejecutar los comportamientos
Sprite.prototype = {
   update: function (time, fps) {
      for (var i=0; i < this.behaviors.length; ++i) {
         if (this.behaviors[i] === undefined) { // You never know 
            return;
         }

         this.behaviors[i].execute(this, time, fps);
      }
   }
};

El método Sprite.update() itera en el comportamiento del sprite, invocando el método execute() de cada comportamiento. Snail Bait invoca continuamente — una vez por fotograma de animación — a todos los comportamientos asociados con todos los sprites visibles. El método execute() de un comportamiento, por lo tanto, no es como la mayoría de los demás métodos, que se invocan relativamente con poca frecuencia; en cambio, cada método execute() actúa como un pequeño motor que está constantemente en funcionamiento.

Ahora que entiende cómo interactúan los sprites y los comportamientos, me concentraré en su implementación individual.

Patrón de diseño Strategy

Los comportamientos son una implementación del patrón de diseño Strategy, que encapsula algoritmos en objetos (consulta Recursos). En tiempo de ejecución, esos algoritmos se pueden mezclar y combinar para asignar un conjunto de comportamientos a un sprite. Los comportamientos proporcionan mayor flexibilidad que la codificación rígida de los algoritmos directamente en los sprites individuales.

Carrera

Snail Bait lleva a cabo dos acciones para que parezca que la corredora está corriendo. Primero, como mencioné en la sección Desplazamiento del Fondo en el segundo artículo de esta serie, el juego desplaza constantemente el fondo, lo que crea la ilusión de que la corredora se mueve horizontalmente. En segundo lugar, el comportamiento de carrera reproduce el ciclo de imágenes de la hoja de sprites del juego, como se muestra en la Figura 2:

Figura 2. Secuencia de carrera
Screen shot of the Snail Bait runner's running sequence

El código del Listado 4 implementa el comportamiento de carrera:

Listado 4. runBehavior de la corredora
var SnailBait =  function () {
   ...
   this.BACKGROUND_VELOCITY = 32, // pixels/second
   this.RUN_ANIMATION_RATE = 17, // frames/second
   ...

   this.runAnimationRate,

   this.runBehavior = {
      // Every runAnimationRate milliseconds, this behavior advances the
      // runner's artist to the next frame of the sprite sheet.

      lastAdvanceTime: 0,
      
      ejecutar: function(sprite, time, fps) {
         if (sprite.runAnimationRate === 0) {
            return;
         }
         
         if (this.lastAdvanceTime === 0) {  // skip first time
            this.lastAdvanceTime = time;
         } 
         else if (time - this.lastAdvanceTime > 1000 / sprite.runAnimationRate) {
            sprite.artist.advance();
            this.lastAdvanceTime = time;
         }
      }
   },
   ...
};

El método execute() del objeto runBehavior() hace avanzar periódicamente a la corredora a la siguiente imagen de la secuencia de carrera en la hoja de sprites. (Puede ver la hoja de sprites de Snail Bait en la sección Personajes y Hojas de Sprites en el cuarto artículo de esta serie).

La frecuencia con la que runBehavior hace avanzar la imagen de la corredora determina la velocidad a la que corre. Ese intervalo de tiempo está establecido según el atributo runAnimationRate . Cuando comienza el juego, la corredora no está corriendo, por lo que el valor inicial del atributo runAnimationRate es cero. Sin embargo, cuando el jugador gira hacia la izquierda o hacia la derecha, Snail Bait establece el atributo en 17 fotogramas por segundo, como se muestra en el Listado 5, y la corredora comienza a correr:

Listado 5. Los giros activan la animación de la carrera
SnailBait.prototype = {
   ...
            
   turnLeft: function () {
      this.bgVelocity = -this.BACKGROUND_VELOCITY;
      this.runner.runAnimationRate = this.RUN_ANIMATION_RATE; // 17 fps, consulta el Listado 4
      this.runnerArtist.cells = this.runnerCellsLeft;
      this.runner.direction = this.LEFT;
   },

   turnRight: function () {
      this.bgVelocity = this.BACKGROUND_VELOCITY;
      this.runner.runAnimationRate = this.RUN_ANIMATION_RATE; // 17 fps, consulta el Listado 4
      this.runnerArtist.cells = this.runnerCellsRight;
      this.runner.direction = this.RIGHT;
   },

};

Flujo de tiempo

Al igual que el comportamiento de carrera, casi todos los comportamientos se predican en el tiempo. Debido a que la animación del juego está en funcionamiento continuamente, muchas funciones que modifican un comportamiento del juego, como turnLeft() y turnRight() delListado 5, lo hacen simplemente estableciendo variables de juego. Cuando el juego toma el siguiente fotograma de animación, esas variables influyen sobre el comportamiento del juego.

Los métodos turnLeft() y turnRight() , que se invocan mediante los manejadores de eventos del teclado del juego, controlan cuán rápido se reproduce el ciclo de secuencias de imágenes de la corredora con el atributo runAnimationRate , tal como mencioné anteriormente. Esos métodos también controlan la velocidad de movimiento de izquierda a derecha de la corredora mediante el atributo bgVelocity , que representa la velocidad de desplazamiento del fondo.


Comportamientos ligeros

El comportamiento de carrera de la corredora que se abordó en la sección anterior posee un estado — específicamente, el de la última vez que el comportamiento hizo avanzar la imagen del sprite. Ese estado vincula estrechamente a la corredora con el comportamiento. Entonces, por ejemplo, si se desea ejecutar otra carrera del sprite, se necesitará otro comportamiento de carrera.

Los comportamientos que no mantienen un estado son más flexibles; por ejemplo, se pueden utilizar como objetos ligeros. Un objeto ligero es una instancia individual de un objeto que muchos otros objetos utilizan de forma simultánea. La Figura 3 ilustra un comportamiento de desplazamiento sin estado que hace que los sprites se desplacen hacia adelante y hacia atrás en una plataforma. Una única instancia de ese comportamiento se utiliza para los botones y el caracol del juego, que se desplazan sobre sus plataformas, como se muestra en la Figura 3:

Figura 3. Secuencia de movimiento de los botones
Screen shot of the Snail Bait button pacing sequence

El Listado 6 muestra el método createButtonSprites() de Snail Bait, que añade el comportamiento de desplazamiento individual a cada botón:

Listado 6. Cómo crear botones de desplazamiento
SnailBait.prototype = {
   ...

   createButtonSprites: function () {
      var button,
          buttonArtist = new SpriteSheetArtist(this.spritesheet,
                                               this.buttonCells),
      goldButtonArtist = new SpriteSheetArtist(this.spritesheet,
                                               this.goldButtonCells);

      for (var i = 0; i < this.buttonData.length; ++i) {
         if (i === this.buttonData.length - 1) {
            button = new Sprite('button',
                                 goldButtonArtist,
                                 [ this.paceBehavior ]);
         }
         else {
            button = new Sprite('button',
                                 buttonArtist,
                                 [ this.paceBehavior ]);
         }

         button.width = this.BUTTON_CELLS_WIDTH;
         button.height = this.BUTTON_CELLS_HEIGHT;

         button.velocityX = this.BUTTON_PACE_VELOCITY;
         button.direction = this.RIGHT;

         this.buttons.push(button);
      }
   },
   ...
};

El Listado 7 muestra paceBehavior :

Listado 7. Comportamiento de desplazamiento
var SnailBait = function () {
   ...

   this.paceBehavior = {
      checkDirection: function (sprite) {
         var sRight = sprite.left + sprite.width,
             pRight = sprite.platform.left + sprite.platform.width;

         if (sRight > pRight && sprite.direction === snailBait.RIGHT) {
            sprite.direction = snailBait.LEFT;
         }
         else if (sprite.left < sprite.platform.left &&
                  sprite.direction === snailBait.LEFT) {
            sprite.direction = snailBait.RIGHT;
         }
      },
      
      moveSprite: function (sprite, fps) {
         var pixelsToMove = sprite.velocityX / fps;

         if (sprite.direction === snailBait.RIGHT) {
            sprite.left += pixelsToMove;
         }
         else {
            sprite.left -= pixelsToMove;
         }
      },

      ejecutar: function (sprite, time, fps) {
         this.checkDirection(sprite);
         this.moveSprite(sprite, fps);
      }
   },

El comportamiento de desplazamiento modifica la posición horizontal de un sprite. El comportamiento implementa movimiento basado en el tiempo para calcular cuántos píxeles se necesitan para mover el sprite en el fotograma de animación actual dividiendo la velocidad del sprite (especificada en píxeles por segundo) por la velocidad de fotogramas de la animación (en fotogramas por segundo), lo que da como resultado la cantidad de píxeles por fotograma. (Consulte la sección Movimiento Basado en el Tiempo en el segundo artículo de esta serie para obtener más información acerca del movimiento basado en el tiempo).


Comportamientos no específicos del juego

Objetos ligeros y estados

paceBehavior se puede utilizar como objeto ligero porque no tiene estado. No tiene estado porque almacena el estado — la posición y la dirección de cada sprite— en los sprites.

El primer comportamiento que mencioné en este artículo — runBehavior — es un comportamiento con estado que está estrechamente vinculado a un único sprite. En cambio paceBehavior, que mencioné posteriormente, es un comportamiento que no tiene estado, es decir, no está vinculado a un único sprite por lo que una única instancia puede ser utilizada por varios sprites.

Los comportamientos se pueden generalizar aun más: se pueden desvincular no solo de sprites individuales, sino del juego en sí. Snail Bait usa tres comportamientos que se pueden aplicar en cualquier juego:

  • bounceBehavior
  • cycleBehavior
  • pulseBehavior

El comportamiento de rebote hace rebotar un sprite hacia arriba y hacia abajo, el comportamiento cíclico reproduce la secuencia de imágenes de un sprite y el comportamiento de pulso manipula la opacidad de un sprite para que parezca que está vibrando.

Los comportamientos de rebote y pulso implican animación no lineal, que abordaré en futuros artículos. El comportamiento cíclico reproduce el ciclo de imágenes de un sprite de forma lineal. Utilizaré la implementación de ese comportamiento para ilustrar los comportamientos que se pueden utilizar en cualquier juego.

Rubíes brillantes

Los rubíes y zafiros de Snail Bait brillan, como se muestra en la Figura 4:

Figura 4. Secuencia de brillo de rubíes
Screen shot of Snail Bait's sparkling-ruby sequence

La hoja de sprites de Snail Bait contiene secuencias de imágenes tanto para los rubíes como para los zafiros; la reproducción de los ciclos de esas imágenes crea el efecto del brillo.

El Listado 8 muestra el método de Snail Bait que crea rubíes. Los zafiros se crean mediante un método casi idéntico (no se muestra). El método createRubySprites() también crea un comportamiento cíclico que cada 500 ms muestra la siguiente imagen de la secuencia de brillo del rubí durante 100 ms.

Listado 8. Cómo crear rubíes
SnailBait.prototype = {
   ...
   createRubySprites: function () {
      var ruby,
          rubyArtist = new SpriteSheetArtist(this.spritesheet, this.rubyCells);
   
      for (var i = 0; i < this.rubyData.length; ++i) {
         ruby = new Sprite('ruby', rubyArtist,
                           [ new CycleBehavior(100,     // animation duration
                                                 500) ]); // interval between animations
         ...
      }
   },
   ...
};

El Listado 9 muestra el comportamiento cíclico:

Listado 9. Comportamiento CycleBehavior
// This behavior advances the sprite artist through
// the sprite's images at a specified animation rate.

CycleBehavior = function (duration, interval) {
   this.duration = duration || 0;  //  milliseconds
   this.interval = interval || 0;
   this.lastAdvance = 0;
};

CycleBehavior.prototype = { 
   ejecutar: function(sprite, time, fps) {
      if (this.lastAdvance === 0) { 
         this.lastAdvance = time;
      }

      // During the interval start advancing if the interval is over

      if (this.interval && sprite.artist.cellIndex === 0) {
         if (time - this.lastAdvance < this.interval) {
            sprite.artist.advance();
            this.lastAdvance = time;
         }
      }
      // Otherwise, if the behavior is cycling, advance if duration is over

      else if (time - this.lastAdvance > this.duration) {
         sprite.artist.advance();
         this.lastAdvance = time;
      }
   }
};

Generalización de comportamientos

Resulta útil buscar oportunidades para generalizar los comportamientos de modo que se puedan utilizar en una variedad más amplia de circunstancias.

El comportamiento cíclico funcionará con cualquier sprite que tenga un personaje en la hoja de sprites, es decir, el comportamiento no es específico de Snail Bait sino que se puede utilizar en otros juegos.El comportamiento de carrera específico del sprite del Listado 4 tiene mucho en común con el comportamiento cíclico no específico del juego del Listado 9; de hecho, el comportamiento cíclico deriva del comportamiento de carrera. (El comportamiento de carrera podría ser un comportamiento cíclico más general, pero el comportamiento de carrera también considera la velocidad de animación de la corredora).


Combinación de comportamientos

Cada comportamiento encapsula acciones específicas como correr, caminar o brillar. Los comportamientos se pueden combinar para lograr efectos más complejos, por ejemplo: mientras el caracol se desplaza hacia adelante y hacia atrás por la plataforma, dispara periódicamente bombas, como se muestra en la Figura 5:

Figura 5. Secuencia de disparos del caracol
Screen shot of Snail Bail's snail shooting sequence

La secuencia de disparos del caracol es una combinación de tres comportamientos:

  • paceBehavior
  • snailShootBehavior
  • snailBombMoveBehavior

paceBehavior y snailShootBehavior están asociados con el caracol; snailBombMoveBehavior está asociado con las bombas. Cuando Snail Bait crea sprites, especifica los primeros dos comportamientos en el constructor de sprites, como se puede observar en el Listado 10:

Listado 10. Cómo crear caracoles
SnailBait.prototype = {
   ...

   createSnailSprites: function () {
      var snail,
          snailArtist = new SpriteSheetArtist(this.spritesheet, this.snailCells);
   
      for (var i = 0; i < this.snailData.length; ++i) {
         snail = new Sprite('snail',
                            snailArtist,
                            [ this.paceBehavior,
                              this.snailShootBehavior,
                              new CycleBehavior(300,  // 300ms per image
                                                1500) // 1.5 seconds between sequences
                            ]);

         snail.width  = this.SNAIL_CELLS_WIDTH;
         snail.height = this.SNAIL_CELLS_HEIGHT;

         snail.velocityX = this.SNAIL_PACE_VELOCITY;
         snail.direction = this.RIGHT;

         this.snails.push(snail); // Push snail onto snails array
      }
   },
};

Cada 1,5 segundos, el comportamiento CycleBehavior del caracol reproduce el ciclo de imágenes de la hoja de sprites, que se muestra en la Figura 6, y muestra cada imagen durante 300 ms lo que crea la ilusión de que el caracol abre y cierra la boca periódicamente. El comportamiento paceBehavior mueve al caracol hacia adelante y hacia atrás en la plataforma.

Figura 6. Imágenes de la hoja de sprites para la secuencia de disparos.
Screen shot of the sprite sheet images for Snail Bait's snail shooting sequence

Las bombas del caracol se crean con el método armSnails() , que se muestra en el Listado 11, lo que en Snail Bait indica el inicio del juego. Ese método itera en los caracoles del juego, crea una bomba para cada caracol, otorga a cada bomba el comportamiento snailBombMoveBehavior y almacena una referencia al caracol en la bomba.

Listado 11. Armas de los caracoles
SnailBait.prototype = {
   ...

   armSnails: function () {
      var snail,
          snailBombArtist = new SpriteSheetArtist(this.spritesheet, this.snailBombCells);

      for (var i=0; i < this.snails.length; ++i) {
         snail = this.snails[i];

         snail.bomb = new Sprite('snail bomb',
                                  snailBombArtist,
                                  [ this.snailBombMoveBehavior ]);

         snail.bomb.width  = snailBait.SNAIL_BOMB_CELLS_WIDTH;
         snail.bomb.height = snailBait.SNAIL_BOMB_CELLS_HEIGHT;

         snail.bomb.top = snail.top + snail.bomb.height/2;
         snail.bomb.left = snail.left + snail.bomb.width/2;
         snail.bomb.visible = false;

         this.sprites.push(snail.bomb);
      }
   },
};

El comportamiento snailShootBehavior dispara la bomba del caracol, como se muestra en el Listado 12:

Listado 12. Cómo disparar bombas
SnailBait.prototype = {
   ...

   this.snailShootBehavior = { // sprite is the snail
      ejecutar: function (sprite, time, fps) {
         var bomb = sprite.bomb;

         if (! bomb.visible && sprite.artist.cellIndex === 2) {
            bomb.left = sprite.left;
            bomb.visible = true;
         }
      }
   },

};

Juegos basados en comportamientos

En un juego basado en comportamientos, una vez que se implementa la infraestructura básica, dar forma al juego es principalmente una cuestión de implementar los comportamientos. Sin la necesidad de centrarse en la mecánica subyacente del juego, como la animación, la velocidad de fotogramas, el desplazamiento del fondo, etc., se puede dar vida al juego casi exclusivamente mediante la implementación de comportamientos. Y como los comportamientos se pueden mezclar y combinar en tiempo de ejecución, se pueden crear rápidamente prototipos de escenarios combinando comportamientos.

Debido a que snailShootBehavior está asociado al caracol, el sprite que pasa al método execute() del comportamiento es el caracol.

El caracol mantiene una referencia a su bomba, de modo que snailShootBehavior accede a la bomba a través del caracol. A continuación, snailShootBehavior verifica si la imagen actual del caracol se encuentra en el extremo derecho de la Figura 6, lo que quiere decir que el caracol está a punto de abrir la boca; de ser así, el comportamiento coloca la bomba en la boca del caracol y la hace visible.

Por lo tanto, el disparo de la bomba del caracol implica ubicar la bomba y hacerla visible en las condiciones correctas. Posteriormente, el movimiento de la bomba es responsabilidad desnailBombMoveBehavior, que se muestra en el Listado 13:

Listado 13. Comportamiento de movimiento de la bomba del caracol
SnailBait = function () {
   this.SNAIL_BOMB_VELOCITY = 450,
   ...
};

SnailBait.prototype = {
   this.snailBombMoveBehavior = {
      ejecutar: function(sprite, time, fps) {  // sprite is the bomb
         if (sprite.visible && snailBait.spriteInView(sprite)) {
            sprite.left -= snailBait.SNAIL_BOMB_VELOCITY / fps;
         }

         if (!snailBait.spriteInView(sprite)) {
            sprite.visible = false;
         }
      }
   },

Mientras la bomba está visible, snailBombMoveBehavior la mueve hacia la izquierda a una velocidad de snailBait.SNAIL_BOMB_VELOCITY (450) píxeles por segundo. Una vez que la bomba deja de ser visible, el comportamiento la hace invisible.


Próximamente

En el próximo artículo de esta serie, desarrollaré en más detalle los comportamientos de tiempo examinando el comportamiento de salto de la corredora. Mostraré cómo implementar un cronómetro JavaScript para controlar el tiempo del salto. Esa técnica fundamental — animaciones temporalizadas — es algo que se utiliza en muchos juegos.


Descargar

DescripciónNombretamaño
Sample codej-html5-game5.zip1.2MB

Recursos

Aprender

Obtener los productos y tecnologías

  • Replica Island: puede descargar el código de este conocido videojuego de plataforma de código abierto para Android.

Comentar

  • Participe en la Comunidad developerWorks. Conéctese con otros usuarios de developerWorks mientras explora los blogs conducidos por desarrolladores, foros, grupos y wikis.

Comentarios

developerWorks: Ingrese

Los campos obligatorios están marcados con un asterisco (*).


¿Necesita un IBM ID?
¿Olvidó su IBM ID?


¿Olvidó su Password?
Cambie su Password

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


La primera vez que inicie sesión en developerWorks, se creará un perfil para usted. La información en su propio perfil (nombre, país/región y nombre de la empresa) se muestra al público y acompañará a cualquier contenido que publique, a menos que opte por la opción de ocultar el nombre de su empresa. Puede actualizar su cuenta de IBM en cualquier momento.

Toda la información enviada es segura.

Elija su nombre para mostrar



La primera vez que inicia sesión en developerWorks se crea un perfil para usted, teniendo que elegir un nombre para mostrar en el mismo. Este nombre acompañará el contenido que usted publique en developerWorks.

Por favor elija un nombre de 3 - 31 caracteres. Su nombre de usuario debe ser único en la comunidad developerWorks y debe ser distinto a su dirección de email por motivos de privacidad.

Los campos obligatorios están marcados con un asterisco (*).

(Por favor elija un nombre de 3 - 31 caracteres.)

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


Toda la información enviada es segura.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=tecnologia Java
ArticleID=930481
ArticleTitle=Desarrollo de Juegos 2D en HTML5: Implementación de comportamientos de sprites
publish-date=05202013