Animaciones e interpolaciones

Este es el paso 14 de 16 del tutorial Gamedev Phaser. Puedes encontrar el c贸digo fuente tal y c贸mo quedar铆a al completar la lecci贸n en Gamedev-Phaser-Content-Kit/demos/lesson14.html.

Para hacer el juego m谩s vistoso y vivo, podemos usar animaciones e interpolaciones. Esto provocar谩 una experencia de juego mejor y m谩s entretenida.  Exploraremos c贸mo implementar animaciones e interpolaciones Phaser en nuestro juego.

Animaciones

En Phaser, las animaciones implican tomar una hoja de sprites externa y mostrar los sprites de forma secuencial. Como ejemplo, haremos que una bola se tambalee cuando toque algo.

En primer lugar toma la hoja de sprites de Github y guardala en el directorio /img.

A continuaci贸n, cargaremos la hoja de c谩lculo : coloca la siguiente linea en la parte inferior de su funci贸n preload():

game.load.spritesheet('ball', 'img/wobble.png', 20, 20);

En lugar de cargar una sola imagen de la bola, podemos cargar toda la hoja de c谩lculo, una colecci贸n de im谩genes diferentes. Mostraremos los sprites de forma secuencial para crear la ilusi贸n de animaci贸n. Los dos par谩metros adicionales del m茅todo spritesheet() determinan el ancho y la altura de cada fotograma en el archivo de spritesheet dado, indicando al programa c贸mo cortarlo para obtener los marcos individuales.

Cargando la animaci贸n

A continuaci贸n ve a tu funci贸n create(), encuentra la linea que carga el sprite de la bola, y debajo coloca la linea que llama a animations.add() que se muestra a continuaci贸n:

ball = game.add.sprite(50, 250, 'ball');
ball.animations.add('wobble', [0,1,0,2,0,1,0,2,0], 24);

Para a帽adir una animaci贸n al objeto usaremos el m茅todo animations.add(), que contiene los siguientes par谩metros:

  • El nombre que elegimos para la animaci贸n.
  • Una matriz que define el orden en que se muestran los cuadros durante la animaci贸n. Si miras de nuevo la imagen wobble.png, ver谩s que hay tres marcos. Phaser extrae estos y almacena las referencias en una matriz: posiciones 0,1, y 2. La matriz anterior dice que estamos mostrando los fotogramas 0, luego 1, despu茅s 0, etc.
  • La tasa de frames, en fps. Ya que estamos ejecutando la animaci贸n en 24fps y hay 9 cuadros, la animaci贸n se mostrar谩 tres veces por segundo.

Aplicando la animaci贸n cuando la pelota golpea el remo

En la llamada al m茅todo arcade.collide() que maneja la colisi贸n entre la pelota y la paleta (la primera linea dentro de  update(), ver abajo) podemos agregar un par谩metro adicional que especifica una funci贸n que se ejecutar谩 cada vez que ocurra la colisi贸n, de la misma manera que la funci贸n ballHitBrick(). Actualiza la primera linea dentro de update() como se muestra a continuaci贸n:

function update() {
    game.physics.arcade.collide(ball, paddle, ballHitPaddle);
    game.physics.arcade.collide(ball, bricks, ballHitBrick);
    paddle.x = game.input.x || game.world.width*0.5;
}

Luego podemos crear la funci贸n ballHitPaddle() (con ball y paddle como par谩metros por defecto), reproduciendo la animaci贸n de oscilaci贸n cuando se llama. A帽ade la funci贸n justo antes de la etiqueta de cierre </script>:

function ballHitPaddle(ball, paddle) {
    ball.animations.play('wobble');
}

La animaci贸n se muestra cada vez que la pelota golpea la paleta. Tambi茅n puedes agregar la llamada a animations.play() dentro de la funci贸n ballHitBrick(), si crees que el juego se ver谩 mejor.

Interpolaciones

Mientras que las animaciones reproducen sprites externos secuencialmente, las interpolaciones animan suavemente las propiedades de un objeto en el mundo del juego como el ancho o la opacidad.

Agreguemos una interpolaci贸n a nuestro juego para hacer que los ladrillos desaparezcan suavemente cuando son golpeados por la pelota. Ve a la funci贸n ballhitBrick(), busca la linea brick.kill(); , y reemplazala por lo siguiente:

var killTween = game.add.tween(brick.scale);
killTween.to({x:0,y:0}, 200, Phaser.Easing.Linear.None);
killTween.onComplete.addOnce(function(){
    brick.kill();
}, this);
killTween.start();

Veamos esto para que puedas saber lo que est谩 pasando:

  1. Al definir una nueva interpolaci贸n, debes especificar qu茅 propiedad se interpolar谩; en nuestro caso, en lugar de ocultar los ladrillos instant谩neamente cuando la bola los golpea, haremos que su ancho y altura se ajusten a cero, por lo que desaparecer谩n. Al final usamos el m茅todo, add.tween(), especificando brick.scale  como el argumento, ya que esto es lo que queremos interpolar.
  2. El m茅todo to() define el estado del objeto al final de la interpolaci贸n. Toma un objeto que contenga los valores finales deseados del par谩metro elegido (la escala toma un valor de escala, 1 es 100% del tama帽o, 0 es 0% del tama帽o, etc.), el tiempo de interpolaci贸n en milisegundos y el tipo de interpolaci贸n.
  3. Tambi茅n a帽adiremos el controlador de eventos opcional onComplete, que define una funci贸n que se ejecutar谩 cuando finalice la interpolaci贸n.
  4. Lo 煤ltimo que debe hacer es iniciar la interpolaci贸n de inmediato utilizando start().

Esa es la versi贸n expandida de la definici贸n de interpolaci贸n, pero tambi茅n podemos usar la sintaxis abreviada:

game.add.tween(brick.scale).to({x:2,y:2}, 500, Phaser.Easing.Elastic.Out, true, 100);

Esta interpolaci贸n duplicar谩 la escala del ladrillo en medio segundo con el uso de Elastic easing, se iniciar谩 autom谩ticamente, y tendr谩 un retardo de 100 milisegundos.

Compara tu c贸digo

Puedes comprobar el c贸digo final de esta lecci贸n en la demo de abajo, y probarlo para entender mejor c贸mo funciona:

Pr贸ximos pasos

Las animaciones y las interpolaciones se ven muy bien, pero podemos agregar m谩s a nuestro juego. En la siguiente lecci贸n veremos c贸mo manejar los botones.