Posted tagged ‘XML’

ActorFactory, mejorando los tiempos de carga

30 May, 2010

Hemos estado tratando de mejorar los tiempos de carga (en PC no se notan pero en PSP sí). El problema es que, cuando se carga un nivel del XML generado por Tiled vamos leyendo dónde colocar los actores (enemigos e ítems). Por cada actor se ha de leer un XML con su información, lo cual es bastante costoso. Para ello hemos implementado un sistema de cacheo de actores el cual estaba pensado desde el inicio pero no había dado tiempo de integrar.

ActorFactory es exactamente lo que su nombre indica, una fábrica de actores. Cuando se crea carga en memoria una copia de cada actor. Cuando necesitamos insertar uno de ellos en el escenario le pedimos que nos devuelva un clon de un tipo de actor en concreto. En vez de parsear un costoso XML se limita a crear una copia del que tiene almacenado ya en memoria y nos lo devuelve. Podéis verlo claramente en el diagrama que acompaña a este artículo.

El rendimiento se ha visto notablemente mejorado y todo marcha viento en popa.

HUD

4 May, 2010

Continuando con el trabajo de “arte” (por llamarlo de alguna manera) traemos el HUD del juego. En el HUD se colocan indicadores visuales para que el jugador conozca el estado de su personaje. Dispondremos de la información del número de vidas, dentaduras y munición de la abuelita. Así mismo, tenemos una barra de vida que irá disminuyendo al recibir impactos y se irá rellenando a medida que recojamos botes de pastillas para la tensión.

Es muy básico pero tampoco era necesario más, simplemente unos indicadores que no entorpezcan la visión del jugador. Hemos implementado una clase HUD que lee de un fichero XML la información a desplegar. De esta manera es posible cambiar el diseño del HUD según las necesidades. Ya sabéis, si alguien se anima puede pasarnos una plantilal mejor que la nuestra, tendrá nuestra gratitud infinita.

Mapa de colisiones para los niveles

23 abril, 2010

Las colisiones con el escenario en Granny’s Bloodbath son de suma importancia (al fin y al cabo tiene un gran componente plataformero) y hasta el momento no las habíamos mencionado. Estos días hemos estado trabajando en el sistema para cargar un nivel a partir del XML generado por Tiled y hemos debido especificar cómo sabíamos de qué tipo es cada tile.

En primer lugar hay que decir que tenemos 3 tipos de tiles:

  • Atravesable: típica pared o nube de fondo, no interfiere para nada con el personaje.
  • No atravesable: un bloque cuya única forma de superar sea saltando por encima.
  • Plataforma: este es el tipo de tile más complejo. Podemos pasar por delante de él como si nada pero si saltamos encima suya nos colocaremos encima. En juegos como Mario hay muchos tiles de este tipo.

A priori Tiled no incorpora ninguna herramienta específica para saber la naturaleza de cada tile de nuestro tileset (paleta de tiles). En los mapas de Tiled podemos incluir propiedades pero incluir una propiedad por cada frame del tileset sería una tarea ardua (demasiado para notros). Es entonces cuando surge la idea del mapa de colisiones.

Una propiedad del escenario creado con Tiled sería la ruta a la imagen del mapa de colisiones de nuestro tileset. Este mapa de colisiones sería una imagen de las mismas dimensiones que el tileset y dividido en cuadritos. Cada cuadro tendría un color plano que equivaldría a un tipo de tile (rojo para el atravesable, verde para el no atravesable y azul para las plataformas).

El constructor de la clase Level se encarga de parsear el fichero XML con los datos de todo el escenario y accede a nivel de píxel a la superficie que alberga el mapa de colisiones. Así podemos conocer el número de tile y el tipo exacto de tile que hay que colocar en cada sección del nivel.

Aún estos cambios no están en la forja pero podéis echarle un vistazo a las imágenes que acompañan al post para comprender el funcionamiento del sistema.

Separando el código de los datos

11 abril, 2010

Algo que estamos teniendo mucho en cuenta a la hora de desarrollar el videojuego es tratar de separar todo lo posible el código de los datos. Esto quiere decir que la información de los niveles, las características de los personajes, el guión del juego, la configuración básica del sistema etc están en ficheros aparte.

¿Qué ventajas aporta? En primer lugar, si quisiéramos cambiar algún parámetro en la jugabilidad como la velocidad o energía de un enemigo no tendríamos que modificar el código fuente. Únicamente acudiríamos a su fichero y cambiaríamos dos números. La implicación directa es que no sufriremos recompilaciones del sistema si necesitamos modificar una tontería. Si cambiamos el fichero de sonido con la voz del narrador en una escena de historia, simplemente tenemos que cambiar el fichero correspondiente de manera que, la próxima vez que se ejecute el juego los cambios se verán reflejados.

Quizás en un videojuego de pequeñas dimensiones como el nuestro no se hace imprescindible pero si pensamos en una producción con algo más de envergadura sí lo es. En este caso los programadores no serían las mismas personas que los grafistas. Imaginad que Pepito es un diseñador y decide cambiar la secuencia de animaciones de un enemigo determinado. Si todo estuviera mezclado necesitaría acudir al código fuente y recompilar para ver el resultado, pero… ¡si el no sabe programar! En cambio, si los datos estuvieran separados del código, simplemente retoca el fichero con los datos del personaje y… ¡voilá¡

No todo iba a ser un viaje por las nubes, como pega aparece la necesidad de contar con un parser que se encargue de leer los ficheros con los datos. Nosotros hemos elegido XML para estructurar nuestros ficheros y hemos precisado de un parser preparado para procesar este tipo de estructuras jerárquicas.

Ejemplos de ficheros con información (no definitivos):

Guión del juego:

<scenes>
	<scene type="story" path="introduccion.xml" />
	<scene type="level" path="nivel1.tmx" />
	<scene type="story" path="intermedio.xml" />
	<scene type="level" path="nivel2.tmx" />
</scenes>

Configuración básica:

<configuracion>
	<pantalla ancho="960" alto="560" bpp="32"/>
	<fps valor="30"/>
</configuracion>

Esperemos que esta idea/enfoque le sea útil a alguien, para nosotros funciona.