lunes, 7 de octubre de 2013

Desarrollo MultiResolucion Parte II - Primer intento

En mi primer intento de llevar a cabo esto, me basé en la técnica de Joshua Granick que pueden verla AQUÍ, de hecho, en base a ese POST saqué mis conclusiones finales expuestas en la primera parte de esta serie de tutoriales.

Básicamente consiste en lo siguiente: se crean los gráficos basándose en una resolución alta; en este primer intento utilicé 960x1704 (960 porque me basé en el post de Joshua Granick y 1704 para obtener la proporción del iPhone5 que me pareció la más rectangular/larga de los dispositivos que considero populares), entonces, en vez de escalar los gráficos para "arriba" escalamos los gráficos para "abajo", de esta forma nos aseguramos que no pierdan su calidad (que es lo que pasa al hacerlo al revés, si hiciste los gráficos a 320x480 y tenes que reescalar a 768x1024 para el IPAD, las imágenes van a verse borrosas y pixeladas).
Imagen representativa, a la izquierda el original y a la derecha el original re-escalado al doble de su tamaño.
Este método me funcionó de maravillas y una prueba de ello ya lo mostré hace tiempo en mi blog con mi proyecto Draw Fast, en donde se puede ver el menu principal del juego en diferentes dispositivos (IPAD, Iphone 4s, Samsung Galaxy S2) incluso podía ajustar la versión FLASH a la resolución que se me antojase sin afectar la calidad gráfica; todo esto utilizando SOLAMENTE un set de gráficos, en este caso los creados a 960x1704.


El siguiente paso fue como encarar la disposición de los objetos, como en mi caso el juego estaba diseñado para jugarlo en PORTRAIT, el alto de la pantalla es lo que va a variar en cada dispositivo, la proporción podía ser 960x1200, 960x1440, 960x???? etc. Para lograr que todos los elementos aparezcan en pantalla utilicé algo que se usa bastante en web... los CONTENEDORES. Así que creé un contenedor TOP, que siempre iba a estar en Y = 0 ; un contenedor BOTTOM cuyo valor Y podía variar dependiendo de la resolución, por ejemplo en un iPhone iba a ser Y = 480, en un iPAD Y = 1024; etc. y finalmente podríamos usar otro que se encuentre en el medio.
En OpenFL y Flash recuerden que las coordenadas x=0; y=0 es en la esquina superior izquierda
De esta forma me aseguro de que los elementos que se encuentran abajo siempre se encuentren visibles, lo único que hay que hacer es mover el contenedor BOTTOM "hacia arriba" para posicionar el resto de los elementos automáticamente, si se fijan en la primera imagen de Draw Fast van a ver que en la versión WEB y IPAD el boton PLAY se encuentra casi tocando el logo, en cambio en la version del iPhone 4s y en especial la del Samsung Galaxy se encuentra más alejado del logo, esto es debido obviamente a la proporción de estas pantallas.

Ahora vamos al código, antes quiero avisar que esto lo hice en OpenFL, mi herramienta de preferencia para desarrollar juegos 2D multiplataforma, utiliza el lenguaje de programación open source HAXE que es muy similar a ActionScript3.


Lo que hice es lo siguiente, el proyecto siempre se maneja a 960 pixeles de ancho y a X pixeles de alto (que varía de acuerdo a la proporción del dispositivo)... lo que hay que hacer es re-escalar los contenedores para que se ajusten a los pixeles de ancho del dispositivo en el que corre. Así que lo que hice fue básicamente lo siguiente:

Clase ValGame.hx
Clase Main.hx
Clase MenuPrincipal.hx
Como observación: La clase MenuPrincipal extiende de SPRITE y todos los contenedores y elementos se encuentran dentro de ella. Podriamos hacer mas sencillo el metodo resize(); de la siguiente manera:


Hasta aquí todo parecía funcionar perfectamente y a medida que iba programando el resto de las pantallas y elementos del juego también insertaba los gráficos correspondientes de cada objeto, y fue ahí cuando un buen día decidí probarlo nuevamente en el iPAD y sorpresa + desgracia mía fue ver como terminó explotando todo. Cada vez que intentaba abrir la aplicación, esta se cerraba inesperadamente, como era de esperarse, cargar varios elementos que fueron diseñados a una resolución elevada como 960x1704 saturaba la memoria del iPAD y ocasionaba que la aplicación se cerrase, y fue ahi cuando me di cuenta que este método lo tenía que perfeccionar, soportando al menos 2 tamaños de gráficos, la HD que sería 960x1704 y una versión re-escalada LD que podía ser 768x1280... o incluso agregar otra menor para dispositivos menos potentes.

Pero eso será en la última parte de este tutorial :D

De cualquier manera esta puede ser una solución válida y relativamente efectiva para ciertos tipos de proyectos, tal vez se podría re-escalar las imágenes a 800 pixeles de ancho en vez de 960 pixeles para ahorrar algo de memoria.

Mientras tanto les recomiendo los siguientes tutoriales que les podría resultar útiles:
Multi resolution development with Flash
Multi-Resolution Development (Starling)
Managing multiple iOS resolutions with Starling Part I
Managing multiple iOS resolutions with Starling Part II
Supporting multpe screen sizes (Construct2 / Scirra)

Ver Desarrollo MultiResolucion Parte I

martes, 1 de octubre de 2013

FlashPunk primeros vistazos

Hace unas semanas atrás decidí empezar a desarrollar un nuevo juego WEB en FLASH y por el estilo del juego decidí utilizar por primera vez un FRAMEWORK para AS3 para no tener problemas de rendimiento al tener varios elementos en pantalla ya que se trata de un RTS que les contaré en detalle más adelante.

Después de investigar a mi parecer lo suficiente finalmente opté por darle una oportunidad al framework FlashPunk. Realmente es una asombrosa herramienta para desarrollar rápidamente juegos, básicamente la estructura es la siguiente: los niveles (o menus) extienden de una clase llamada WORLD que a su vez puede contener varios objetos que interactúan entre si conocidos como entidades que extienden de la clase ENTITY.

Uno de los primeros inconvenientes (o diferencias) con las que me encontre fue que FlashPunk no utiliza MovieClips, por lo que, por ejemplo, tuve que desarrollar una clase "BOTON" que extiende de un ENTITY para poder realizar los cambios de gráficos al pasar el mouse encima, hacer click, etc.

Seguido a ese "problema" me encontré con que FlashPunk no se maneja utilizando los eventos del mouse que trae Flash, por lo que los eventos MOUSE como ROLL OVER, ROLL OUT, CLICK los tuve que chequear manualmente si existia una "colision" del cursor con el objeto.


Esto en un determinado momento derivó a otro problema que por suerte ya se me presentó desarrollando un MENU del juego. Que pasa cuando tenes 2 entidades/objetos que reaccionan a un evento del mouse y estan superpuestos? Me paso que al hacer 1 click, los 2 objetos superpuestos lanzaban su acción "clicked();". En mi juego RTS probablemente en algún punto podía llegar a tener más de una unidad superpuesta con otra, y si el jugador quisiese seleccionar 1 de ellas pues con esto terminaría seleccionándola a todas.

Despues de encontrar una solucion no tan practica o bien hecha (utilice una variable estatica), finalmente tomé coraje y me anime a postear el problema en el foro de la comunidad de FlashPunk, y digo me anime porque realmente pensé que era un problema muy tonto y me daba algo de verguenza realizar una consulta de tremenda calamidad u.u.

El hecho es que ese POST ya tiene unas 12 respuestas y varias formas (por cierto muy buenas) para resolver ese problema. Pueden ver el post aqui: http://developers.useflashpunk.net/t/clicking-selecting-objects-entities/616

Si son desarrolladores y quieren hacer juegos WEB con FLASH les recomiendo que le den un vistazo al framework y que lo prueben. Además hay una version para Haxe llamada HaxePunk y que funciona con OpenFL, mi herramienta de desarrollo preferida para juegos 2D MOBILE multiplataforma.