miércoles, 16 de abril de 2008

Sprites

El siguiente paso en nuestro juego será poner a nuestro héroe a recorrer el mundo que le hemos creado en la anterior entrega.

Como hemos hecho que lo que se mueva sea el fondo, el muñeco estará en el centro de la pantalla.

Pero ¿Qué es un Sprite? Un sprite es un elemento gráfico que se superpone a los fondos, y que gracias a las transparencias, no borra a estos. Vamos a ver nuestro primer sprite:

Muy bien. En este Sprite tenemos a nuestro héroe con las distintas posturas que tendrá en el juego. Guardaremos dicha imagen en C:\devDS\PokemonDS\source\gfx como heroe.png. Para cargar la imagen en el juego, realizaremos los siguientes pasos:
  1. Ejecutar PAGC Frontend (el que está dentro de la carpeta gfx de nuestro source)
  2. Load INI (para cargar el INI donde tenemos el fondo, que si no perdemos el fondo!)
  3. En la pestaña de Sprites cargamos la imagen heroe.png
  4. Save and Convert
Como muchos os habéis imaginado el color rosa es el color transparente, y el espacio que hay entre cada muñeco es porque la DS (o PALib) soporta los siguientes tamaños de Sprites:

8x8 16x8 32x8
8x16 16x16 32x16
8x32 16x32 32x32 64x32
32x64 64x64

En nuestro caso el héroe entraba en una caja de 16x32 y como tenemos 9 posturas, pues la imagen mide 16 x 288.
¿Dónde están las posturas mirando a la izquierda? Pues resulta que podemos rotar al sprite, así que no nos van a hacer falta (porque para este Sprite el ir a la izquierda o a la derecha es idéntico, cosa que no siempre es así).

Pongamos el código necesario. Primero, añadiremos una nueva constante a nuestro fichero devnintendods.h, que quedará así:

#define SCREEN_TOP 1
#define SCREEN_BOTTOM 0

#define BACKGROUND_ZERO 0
#define BACKGROUND_ONE 1
#define BACKGROUND_TWO 2
#define BACKGROUND_THREE 3

#define COLOR_MODE_256 1

y después así es como quedará el main.c:
// Includes
#include <pa9.h> // Include for PA_Lib
#include "gfx/all_gfx.h" #include "gfx/all_gfx.c" #include "devnintendods.h" #define BACKGROUND_X 56 #define BACKGROUND_Y 132 #define HEROE_PALLETE 0 #define HEROE_SPRITE 0 #define HEROE_X 120 #define HEROE_Y 88 int main(int argc, char ** argv) { PA_Init(); PA_InitVBL(); PA_EasyBgLoad(SCREEN_TOP, BACKGROUND_THREE, fondo); PA_InitParallaxX(SCREEN_TOP, 0, 0, 256, 0); PA_InitParallaxY(SCREEN_TOP, 0, 0, 256, 0); PA_LoadSpritePal(SCREEN_TOP, HEROE_PALLETE,(void*)heroe_Pal); PA_CreateSprite(SCREEN_TOP, HEROE_SPRITE, (void*)heroe_Sprite, OBJ_SIZE_16X32, COLOR_MODE_256, HEROE_PALLETE, HEROE_X, HEROE_Y); PA_SetSpritePrio(SCREEN_TOP, HEROE_SPRITE, BACKGROUND_TWO); s32 fondoX = BACKGROUND_X; s32 fondoY = BACKGROUND_Y; while (1) { fondoX += Pad.Held.Right - Pad.Held.Left; fondoY += Pad.Held.Down - Pad.Held.Up; if (Pad.Held.Up) { PA_SetSpriteAnim(SCREEN_TOP, HEROE_SPRITE, 4); PA_SetSpriteHflip(SCREEN_TOP, HEROE_SPRITE, 0); } if (Pad.Held.Down) { PA_SetSpriteAnim(SCREEN_TOP, HEROE_SPRITE, 0); PA_SetSpriteHflip(SCREEN_TOP, HEROE_SPRITE, 0); } if (Pad.Held.Left) { PA_SetSpriteAnim(SCREEN_TOP, HEROE_SPRITE, 6); PA_SetSpriteHflip(SCREEN_TOP, HEROE_SPRITE, 1); } if (Pad.Held.Right) { PA_SetSpriteAnim(SCREEN_TOP, HEROE_SPRITE, 6); PA_SetSpriteHflip(SCREEN_TOP, HEROE_SPRITE, 0); } PA_EasyBgScrollXY(SCREEN_TOP, BACKGROUND_THREE, fondoX, fondoY); PA_WaitForVBL(); } return 0; }

El código es muy sencillo: se carga la paleta de colores del sprite, podemos tener paletas compartidas y así ahorramos recursos, y después se crea el sprite. Si os fijáis las variables heroe_Pal y heroe_Sprite las crea el programa PAGC.

Sólo nos falta animar a nuestro héroe. Empezaremos por partes, para esta entrega con girarlo dependiendo de la dirección en que nos desplacemos será suficiente. if (Pad.Held.Left) nos indicará si se ha pulsado el cursor izquierdo, por lo que ponemos el Sprite en el primer frame de la posición izquierda y lo giramos. if (Pad.Held.Right) nos indica que hemos pulsado el cursor derecho y ponemos el frame en la primera posición que refleja el ir a la derecha. Aunque en este caso no haría falta girar el Sprite, como es posible que lo hayamos hecho al ir a la izquierda, tendremos que anular dicho giro.

Vemos una imagen del juego:

Y esto es todo. En la próxima entrega haremos que nuestro héroe mueva las piernas y los brazos.

Un saludo

2 comentarios:

Anónimo dijo...

haz abandonado la pagina web?sigue ombre que esta mubien!

Carlos dijo...

Oye, una cosa, para que se supone que se necesitan los #define?
Lo cierto es que no entiendo muy bien el uso de los #define, con lo que agradeceria que lo esplicaras...xD
Por cieerto, por queno te creas una pagina web? Estaria mejor que un blog, no cres?