sábado, 16 de mayo de 2015

Manipulación de gráficos SVG


Siempre que se trabaja con un formato de imagen tradicional (archivos bmp, jpeg, gif, png, etc..) se debe tener en cuenta sus limitaciones. 

En nuestro caso, y me refiero a la programación de juegos, es su escalabilidad o la propiedad que tiene una imagen para cambiar de tamaño sin perder resolución la que por lo general nos puede dar problemas..




De qué cuernos está hablando este tipo quizás alguno se pregunte...bien, veamos un ejemplo:


Tenemos un sprite que muestra el logo de haxe, con un tamaño de digamos 30x30 píxeles el cual, por algún motivo debemos agrandar (zoom) en cierto punto de nuestra aplicación.

El método o propiedad que se utiliza en estos casos se llama scale(x,y o z).

digamos: haxelogo.scaleX = 1.1 ….haxelogo.scaleY = 2.3...y así.

El valor (float) que le asignamos va a establecer la proporción en la cual el sprite va a ser agrandado o disminuido..similar al zoom de un editor de imágenes (partiendo que el tamaño original es igual a 1 o 100%, un valor de 1.5 representaría la imagen agrandada en un 50% más (150%)).

Pero, vemos que a medida que subimos la escala (o cambiamos el aspecto de la pantalla), nuestro logo comienza a verse cada vez más pixelado, o estirado...deformado.

Típico efecto serrucho


Esto se debe a muchos factores, como por ejemplo (y tratándose especialmente de haxe):

  • La plataforma en la cual corra nuestro juego (no es lo mismo móviles que escritorio).
  • La densidad en la cual muestra el sistema los gráficos o la configuración de los DPI.
  • El motor de renderización, la placa de vídeo..drivers,etc.

Misma imagen, pero pesa
10 veces más.
Si bien, el problema puede solucionarse con solo generar imágenes de mayor calidad (o diversos conjuntos dependiendo de la resolución o tamaños de pantalla, etc), ello trae aparejado otro problema, que es el rendimiento.

Mayor calidad de imágenes o mayor cantidad de colecciones equivale a más cantidad de memoria a utilizar, más espacio de almacenamiento, más tiempo de carga..etc.

Entonces, debemos encontrar un punto de equilibrio entre calidad gráfica o visual y rendimiento.

Los formatos clásicos de imágenes (como para dar una referencia muy corta) son creados a base de un sistema de coordenadas donde cada una de ellas representa un punto y un color. Cada uno de estos puntos (pixel digamos) está íntimamente ligado a los otros pixels que lo rodean y así forman un todo (imagen completa).


Lo mismo pero en
formato SVG pesa solo 4kb
Existe otro tipo de formato para manipular imágenes que tiene la particularidad de que guarda vectores o formas geométricas independientes, que al combinarse forman la imagen.

Dentro del conjunto de gráficos vectoriales, se encuentra un standard que tiene la particularidad de poder cambiar de tamaño sin los efectos del típico serrucho (son escalables).

Me refiero a los archivos SVG o Scalable Vector Graphics en inglés.

Si ven el esqueleto de una archivo SVG, reconocerán su estructura de inmediato

El código del ejemplo para el logo de Haxe

...sep, acertaron...es otro de los tantos “dialectos” que existen con XML.

No quiero entrar en detalles (los cuales se encuentran en el enlace a wikipedia), simplemente hacer referencia a que el uso de este tipo de gráficos tiene sus ventajas (y desventajas).

Ventajas:

  • Como ya dije, son escalables. No importa la escala aquí, lucirán bien.
  • Soportado por la mayoría de los navegadores de forma nativa.
  • Su tamaño en disco, por lo general es menor a que su homónimo en formato Bitmap.
  • Modificable en tiempo real sin mucho procesamiento algorítmico o filtros.

Desventajas:

  • Quizás la mayor de todas es la falta de documentación.
  • Por lo dicho arriba, la implementación puede complicarse un poco.
  • Pocas herramientas (Libres o incluso pagas) para trabajar con ellos.
  • No es soportado por todas las plataformas.

Una de las pocas herramientas (de uso gratuito) que conozco para manipularlos es Inkscape.

Inkscape es el clásico (Gratis)

Soporta una gran variedad de formatos y dentro del tipo “SVG” muchos más (Algunos no están muy estandarizados y pueden dar problemas. Mi recomendación es probar).

Sinceramente lo he utilizado muy poco con este tipo de archivos y siempre fue para crear interfaces para aplicaciones (Botones, Checkboxes, etc).





Pueden encontrar más recursos en : http://wiki.inkscape.org/wiki/index.php/Galleries

Otro muy básico, pero online puede utilizarse desde Aquí. (Para guardar el archivo, simplemente aben un editor de texto y copian lo generado).

svg-edit se puede utilizar desde cualquier navegador

Antes de pasar al ejemplo, quiero aclarar que la librería utilizada es muy básica y no está documentada. Tengan en cuenta que es un formato de imágenes que no se utiliza a menudo en la creación de juegos (personajes, objetos que deben moverse rápidamente, etc.), sólo para crear interfaces que puedan ser modificadas rápidamente y sobretodo livianas.

Bien, tenemos una imagen con formato SVG, pero cómo la utilizamos con Haxe?

Sencillo. En primer lugar, debemos bajar una librería nueva, que en mi caso ya está instalada.

Instalando SVG


Luego, debemos agregarla a project.xml para poder acceder a ella:

project.xml debe incluirla


y ya se encuentra lista para importarla en el proyecto:




Primero es cargado como un asset para ser analizado por la librería.
Creamos un objeto contenedor (Objeto shape en este caso) y luego es asociado a dicho objeto:


El método render debe incluir el contenedor (boton_svg), coordenadas(x,y) y tamaño(x,y)

Básicamente eso es todo. A partir de aquí se trabaja con el objeto como siempre.

El ejemplo funcionando...
mostrando el ejemplo :P


En el ejemplo que van a encontrar en Git, se muestra la comparación entre los dos tipos de imágenes. Simplemente son dos sprites con con diferentes texturas (uno es PNG, el otro SVG) que toman diferente tamaño de forma aleatoria cada segundo.
Luego tenemos un botón (también SVG) que pasa de pantalla normal a completa y viceversa.





Si no se hace así, el texto no se mostrará

Les dejo un tip. La librería SVG no soporta el manejo de cuadros de texto dentro de la imagen. Si desean mostrar un texto dentro del archivo svg (como la estrella que es en realidad un botón), deberán pasar el objeto (texto) a trayecto dentro de Inkscape, de lo contrario el texto no se mostrará.

Eso es todo por ahora sobre el formato SVG y Haxe. Fue solo una introducción y queda muchísimo por ver (por ejemplo como manipular las figuras geométricas por separado).

Descarguen el ejemplo desde Aquí y experimenten. En la próxima entrada juntamos algunas cosas aprendidas hasta ahora para dar le forma a un ejemplo completo.

Diviértanse, un saludo.-