sábado, 21 de marzo de 2015

Aplicaciones y Rendmimiento (Segunda Parte)


Continuando con la serie, veamos de qué se tratan los Tiles o mosaicos.  En teoría es un conjunto de imágenes agrupadas en un solo archivo que, mediante una serie de algoritmos, vamos extrayendo una a una para alojarlas en memoria y posteriormente utilizarlas. Presenta ventajas y desventajas este método de manipular imágenes, pero por lo general y a largo plazo se vuelve casi imprescindible.





El programa que arrancamos viendo la semana pasada usa este método para cargar y mostrar las figuras en la pantalla.

Ahora con un ejemplo sencillo; Supongamos que vamos a utilizar todos los elementos de esta imagen:



Con los métodos que vimos hasta ahora, deberíamos:

  • Abrir un editor de imágenes
  • Cortar cada una de ellas
  • Guardarlas en archivos de forma individual
  • Escribir el código para cargar cada una por separado.

Un infierno..y son solamente 256..

Imaginen que se va complicando un poco más:



... :/

OpenFL nos va a dar una mano mediante el uso del método openfl.display.Tilesheet (similar a AS3, pero mejor que éste ya que está optimizado para usar el GPU)

Consiste en obtener una sección de la imagen (Tile) mediante el uso de coordenadas y guardar esos datos en una arreglo o matriz (array).

Digamos por ejemplo que tenemos esta imagen:



Para extraer las 4 casas y convertirlas en Tiles, deberíamos de hacer:

 La imagen muestra el código completo, veamos el resultado en pantalla:







Desarrollemos un poco el código:

La variable “sabana” es el asset (archivo de imágenes) donde se encuentran las casitas.
Luego declaramos el objeto:

var tilesheet = new Tilesheet (sabana);

y comenzamos a recortar en secciones y a guardarlas:




En el ejemplo, el alto se mantiene constante en 100 pixels (que es el alto de la imagen). El largo varía un poco (88,84,81,88) debido a que los rectangulos de colores los dibujé a mano.

Podríamos haber utilizado un bucle (for..in) pero son pocas las imágenes y en mi opinión queda más descriptivo. En la entrada anterior del blog con el ejemplo de los FPS, utilizo 2 bucles para rellenar el array con las 256 muestras.

El indice arranca en cero y se auto incrementa de forma automática.

Una vez cargado el arreglo, pasamos a mostrarlas:

La forma más simple de su uso es  [PosX, PosY, Indice]

tilesheet.drawTiles(graphics, [50, 50, 0], false);



Además, la funcion puede manejar algunos valores extra como por ejemplo:



Si se usa el flag de rotación, habrá que agregar un cuarto valor al array (en radianes)

Lo mismo sucede si se modifica la escala:



Pueden utilizarse conjuntamente varios, siempre que se respete el orden de los valores dentro del arreglo.

El unico modificador que funciona diferente es Tilesheet.TILE_TRANS_2x2:



Al estar presente dentro de la función se ignoran rotación y escala. Debe tener los 4 valores presentes dentro del arreglo o producirá un error.

Volviendo al ejemplo de los FPS, tenemos dentro del evento Tiempo (timer) que existe un bucle para cargar un array con valores aleatorios.



Como puede verse es uno de los recursos más versátiles y potentes dentro de las librerías que OpenFL tiene a su disposición. A ello,hay que sumarle la rapidez y eficiencia con la que Haxe maneja los arreglos.

Es la combinación ideal para generar gráficos con un cierto grado de complejidad con pocas líneas de código. Los dos frameworks más usados en la actualidad que se utilizan para juegos en 2D hacen uso de ella.




Otro de los ejemplos más conocidos y utilizados es la generación aleatoria de Mapas, Niveles, etc.
 
Quizás el tema se haya desvirtuado un poco, pero quiero terminar la entrada haciendo referencia a un libro (Lamentablemente en Inglés por ahora)  escrito por Bob Nystrom, que es exactamente a dónde apunta esta entrada: código y eficiencia al mismo tiempo.

Página oficial, Web del autor y su libro aquí

Recomiendo que le den una ojeada, especialmente éste capítulo.


Seguiremos con este tema y un nuevo ejemplo en la próxima.