jueves, 23 de abril de 2015

Spritesheet y Sparrow(xml) Parte 2


ShoeBox nos da la oportunidad de generar Atlas de imágenes con formato Sparrow que podemos implementar en haxe de forma transparente en cuestión de minutos (entre otras opciones). 


A continuación veremos como tratar estos archivos para generar sprites.


Si vienen leyendo del post anterior, sabrán que nos quedamos en las “contras” de utilizar Sparrow como formato para nuestro Atlas.

Tenemos que: para mostrar un Sprite animado con esta librería hace falta:

  • Un Atlas o secuencia de imágenes.
  • Un objeto Spritesheet
  • Definir el comportamiento que va a tener nuestro sprite.
  • Un objeto AnimatedSprite.


En la entrada anterior importamos las librerías que necesitamos, luego tenemos que alojar nuestro Atlas dentro de la carpeta Assets como ya hemos visto anteriormente para poder utilizarlo.


El archivo xml generado por el empaquetador (ShowBox) es tratado como texto, y lo declaramos de esa forma:

var datos = Assets.getText("img/mostri.xml");

Luego inicializamos la instancia de AnimatedSprite que va a alojar a nuestro objeto sprite animado.

var dino_ani:AnimatedSprite;

y comienza la diversión:

El primer paso es declarar la variable(objeto) que va a llamar a la función encargada de importar el archivo xml.

var dino:Spritesheet = SparrowImporter.parse(datos, "img");

Simplemente le estamos pasando los valores a la función con la ruta de acceso a nuestro archivo de datos (xml).

SparrowImporter.parse(archivo, carpeta)

La función va a recorrer la imagen del Atlas dependiendo de los valores que encuentre en el archivo xml.
Como se habrán dado cuenta, no le pasamos el nombre del archivo de la imagen, sólo el nombre del archivo de datos.

La función toma el nombre del archivo de imágenes que se encuentra declarado en el xml (<TextureAtlas imagePath="archivo.png">)




Luego retiene en una matriz (array) los datos que vaya encontrando en el subnodo (SubTexture).

Se puede notar que es muchísimo más sencillo de implementar que todo lo visto hasta ahora, pero esto no termina acá.
Pasamos luego a inicializar los comportamientos que va a tener nuestro sprite animado.

El formato es:

nuestro_sprite.addBehavior(new BehaviorData("nombre", [n1,n2,....n], repetir, fps));

Donde tenemos que “nombre” es una declaración abstracta o identificador arbitrario definido por nosotros. Por ejemplo podríamos tener “parado” o “caminando”, “saltando, “muerto”, etc.

[n1,n2,....n] es la secuencia de imágenes que van a formar nuestra animación y va a depender del orden en cómo la función SparrowImporter las haya tomado del Atlas.

En realidad el orden dentro del Atlas no importa mucho, sino que la secuencia sea la que nosotros tengamos en mente, ya que muchas veces los programas como ShoeBox o TexturePacker van a intentar empaquetar las imágenes separadas en un solo archivo, pero intentando optimizarlo para que sea lo más pequeño posible.

Por ejemplo, podríamos tener que  la secuencia o comportamiento (Behavior en inglés) de nuestro sprite “corriendo” sean las imágenes 4,5,6...o si debe “saltar” sean las imágenes 10,11,18,56...etc.


En el caso de nuestro ejemplo, el dinosaurio se encuentra parado y lo único que hace es parpadear..por eso, la secuencia, para ponerla en un término abstracto, es: ojos cerrados -> ojos poco abiertos -> medianamente abiertos -> totalmente abiertos -> medianamente abiertos -> poco abiertos -> cerrados [0, 1, 2, 3, 2, 1]



El parámetro repetir (lógico: verdadero o falso), le dice al constructor si queremos que la animación tenga un bucle (loop). Dicho de otro modo, si debe repetir la secuencia al terminar o no.

FPS, es el valor en cuadros por segundo que va a tomar nuestra animación o secuencia.

Obviamente podemos generar tantos comportamientos como queramos. Divertido no?
Bien. Tenemos nuestro objeto/sprite animado ya creado, los comportamientos inicializados.

Para el caso de este simple ejemplo, solo vamos a tener un comportamiento (Behavior) que mostrar y lo situamos al inicio.

dino_ani.showBehavior("parado");


Lógicamente, todos estos comportamientos deben de actualizar su secuencia de imágenes de alguna forma.

Para este caso, se utiliza el Tiempo Delta, que no es otra cosa que la diferencia entre el tiempo actual y la última vez que se actualizó. El “tiempo” en nuestro caso está medido en cuadros por segundo y por ello, toda la subrutina debe ir dentro de un evento que llame a una función en esos términos.



La funcionalidad que presenta la librería es muy interesante para generar animaciones sin mucho esfuerzo.

Pero aquí no termina!.. Al examinar un poco más en profundidad el código nos encontramos con varios métodos que todavía no hemos visto.
Quizás en las próximas entradas.

Jueguen con esta librería que tiene mucho para ofrecer (además es muy entretenido)



Como siempre, pueden descargar el fuente en GitHub.