21 octubre 2008

Remake (parcial) de Fruity Frank... 07 - Mapa para dibujar el fondo

Ahora vamos a aplicar nuestros conocimientos de "arrays" para que el fondo no sea prefijado, sino que se pueda crear y modificar "al vuelo".

En vez de tener una imagen con todo el tamaño del fondo (por ejemplo 640x480 puntos), tendremos varias imágenes pequeñas, por ejemplo de 40x30 píxeles.

La primera ventaja evidente es el ahorro de memoria: una pantalla de 640x480 puntos con sólo 256 colores necesitará 307.200 bytes para almacenarse. Si en nuestro mapa hay cinco tipos de elementos (dos tipos de fondo, un tipo de obstáculo, dos tipos de enemigo), necesitaremos 5 x 40 x30 = 6.000 bytes; además el mapa tendría 16 columnas (640/40) y 16 filas (480/30), lo que supone 16 x 16 = 256 bytes para guardar el mapa. En total, necesitamos 6.256 bytes para una pantalla... casi 50 veces menos que antes (y esta proporción puede ser aún mayor, si en la segunda pantalla hay elementos comunes con la primera).

Pero hay muchas más ventajas. Por ejemplo:


  • Es mucho más fácil modificar ese "mapa" que modificar una imagen, en caso de que queramos cambiar la estructura de la pantalla durante el juego (por ejemplo, si nuestro personaje "recoge un premio" o destruye un obstáculo).

  • Este mapa permite una forma muy fácil de comprobar colisiones entre objetos: si nuestro personaje se mueve a la casilla (2,3) y en esa casilla hay un "premio", deberemos aumentar la cantidad de puntos, etc.



¿Y cómo creamos ese mapa? Podría ser un "array de caracteres", formado por varias filas (un array de dos dimensiones), en el que cada letra tenga un significado especial:

    char mapa[10][16]={
"XCXXMXXX XMCXXX",
"MXXCXXXX XMXCMM",
"XMCXXXXX XCXXXC",
"XXCXCXCX XXXXCX",
" ",
"XXMCXMXX XCXXXX",
"XXXXXXXX XXXMXX",
"XXXXXCXX XXXXXX",
"XXXXXCXX XXXCXX",
"XXXXXXXX CXCXXC"
};


En este ejemplo, una X indicaría una casilla del fondo que se debe dibujar, una C sería una cereza, una M sería una manzana, y un espacio en blanco sería una casilla en la que no hay que dibujar nada.

Siendo prácticos, sería mejor no usar esos valores 10 y 16 para indicar el tamaño, sino usar dos constantes, llamadas MAXFILAS y MAXCOLS (por ejemplo), de modo que podamos revisar el mapa con dos bucles "for", así:

        for (int i=0; i<MAXFILAS; i++)
for (int j=0; j<MAXCOLS; j++) {
if (mapa1[i][j] == 'X')
SDLA_dibujarImagenOculta(fondoNivel1, ...


Entonces, el primer paso, antes de este doble "for", no sería dibujar el fondo, que ya no existe como un único elemento, sino borrar la pantalla oculta, para luego dibujar sobre ella elemento a elemento:

        SDLA_borrarPantallaOculta(0,0,0); // Borro en negro


El siguiente paso que daremos será usar este mapa para comprobar "colisiones", pero eso llegará dentro de poco, en la próxima entrega...

Como siempre, puedes ver todo el proyecto en: code.google.com/p/fruityfrank