lunes, 5 de enero de 2009

Fundido de pantalla

Vamos a realizar un último efecto gráfico en el juego, un Fundido de pantalla. En este caso es simplemente el oscurecimiento de la pantalla. Esto se consigue con la función PA_SetBrightness.

De esta forma cargaremos un par de portadas al juego y lo dejaremos acabado.

Las portadas serán estas:
la portada:
y la subportada:

Crearemos una función que las cargue y las descargue. Usaremos el Stylus para pulsar sobre la pantalla y poder así empezar el juego.

Deberemos añadir a nuestro código la definición de la función y la función cargarPortadas.

#include <PA9.h>

#include "gfx/all_gfx.h"
#include "gfx/all_gfx.c"

#include "devnintendods.h"

#define BACKGROUND_X 80
#define BACKGROUND_Y 132

#define HEROE_PALLETE 0
#define HEROE_SPRITE 0
#define HEROE_REFLEJO_SPRITE 1
#define HEROE_X 120
#define HEROE_Y 88
#define HEROE_VELOCIDAD 5

#define ANIMACION_PAUSA 0
#define ANIMACION_ABAJO 1
#define ANIMACION_ARRIBA 2
#define ANIMACION_IZQUIERDA 3
#define ANIMACION_DERECHA 4

#define ESPACIO_LIBRE 0

u8 obtenerBaldosa(s32 x, s32 y);
void cargarPortadas();

int main(int argc, char ** argv) {
    PA_Init();
    PA_InitVBL();

    cargarPortadas();

    PA_EasyBgLoad(SCREEN_TOP, BACKGROUND_TWO, fondo);
    PA_EasyBgLoad(SCREEN_TOP, BACKGROUND_THREE, agua);
    PA_EasyBgLoad(SCREEN_TOP, BACKGROUND_ONE, sobre_fondo);
    
    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);

    PA_CreateSprite(SCREEN_TOP, HEROE_REFLEJO_SPRITE, (void*)heroe_Sprite, OBJ_SIZE_16X32, COLOR_MODE_256, HEROE_PALLETE, HEROE_X, HEROE_Y + 8);
    PA_SetSpritePrio(SCREEN_TOP, HEROE_REFLEJO_SPRITE, BACKGROUND_THREE);
    PA_SetSpriteVflip(SCREEN_TOP, HEROE_REFLEJO_SPRITE, 1);
    PA_SetSpriteMode(SCREEN_TOP, HEROE_REFLEJO_SPRITE, 1);
    PA_EnableSpecialFx(SCREEN_TOP, SFX_ALPHA, 0, SFX_BG0 | SFX_BG1 | SFX_BG2 | SFX_BG3 | SFX_BD);
    PA_SetSFXAlpha(SCREEN_TOP, 12, 15);

    s32 fondoX = BACKGROUND_X;
    s32 fondoY = BACKGROUND_Y;
    s32 estadoAnimacion = ANIMACION_PAUSA;

    PA_InitParallaxX(SCREEN_TOP, 0, 256, 256, 0);
    PA_InitParallaxY(SCREEN_TOP, 0, 256, 256, 0);

    PA_ParallaxScrollXY(SCREEN_TOP, fondoX, fondoY);
    PA_WaitForVBL();
    //PA_InitText(SCREEN_BOTTOM, BACKGROUND_ZERO); // para debugear!!
    while  (1) {
        if (Pad.Held.Up) {
            if (estadoAnimacion != ANIMACION_ARRIBA) {
                estadoAnimacion = ANIMACION_ARRIBA;
                PA_StartSpriteAnim(SCREEN_TOP, HEROE_SPRITE, 3, 5, HEROE_VELOCIDAD);
                PA_SetSpriteHflip(SCREEN_TOP, HEROE_SPRITE, 0);

                PA_StartSpriteAnim(SCREEN_TOP, HEROE_REFLEJO_SPRITE, 3, 5, HEROE_VELOCIDAD);
                PA_SetSpriteHflip(SCREEN_TOP, HEROE_REFLEJO_SPRITE, 0);
            }
        } else if (Pad.Held.Down) {
            if (estadoAnimacion != ANIMACION_ABAJO) {
                estadoAnimacion = ANIMACION_ABAJO;
                PA_StartSpriteAnim(SCREEN_TOP, HEROE_SPRITE, 0, 2, HEROE_VELOCIDAD);
                PA_SetSpriteHflip(SCREEN_TOP, HEROE_SPRITE, 0);
                
                PA_StartSpriteAnim(SCREEN_TOP, HEROE_REFLEJO_SPRITE, 0, 2, HEROE_VELOCIDAD);
                PA_SetSpriteHflip(SCREEN_TOP, HEROE_REFLEJO_SPRITE, 0);
            }
        } else if (Pad.Held.Left) {
            if (estadoAnimacion != ANIMACION_IZQUIERDA) {
                estadoAnimacion = ANIMACION_IZQUIERDA;
                PA_StartSpriteAnim(SCREEN_TOP, HEROE_SPRITE, 6, 8, HEROE_VELOCIDAD);
                PA_SetSpriteHflip(SCREEN_TOP, HEROE_SPRITE, 1);

                PA_StartSpriteAnim(SCREEN_TOP, HEROE_REFLEJO_SPRITE, 6, 8, HEROE_VELOCIDAD);
                PA_SetSpriteHflip(SCREEN_TOP, HEROE_REFLEJO_SPRITE, 1);
            }
        } else if (Pad.Held.Right) {
            if (estadoAnimacion != ANIMACION_DERECHA) {
                estadoAnimacion = ANIMACION_DERECHA;
                PA_StartSpriteAnim(SCREEN_TOP, HEROE_SPRITE, 6, 8, HEROE_VELOCIDAD);
                PA_SetSpriteHflip(SCREEN_TOP, HEROE_SPRITE, 0);

                PA_StartSpriteAnim(SCREEN_TOP, HEROE_REFLEJO_SPRITE, 6, 8, HEROE_VELOCIDAD);
                PA_SetSpriteHflip(SCREEN_TOP, HEROE_REFLEJO_SPRITE, 0);
            }
        } else {
            estadoAnimacion = ANIMACION_PAUSA;
            PA_StopSpriteAnim(SCREEN_TOP, HEROE_SPRITE);
            PA_StopSpriteAnim(SCREEN_TOP, HEROE_REFLEJO_SPRITE);
        }
        if (estadoAnimacion != ANIMACION_PAUSA) {
            s32 x = fondoX + Pad.Held.Right - Pad.Held.Left;
            s32 y = fondoY + Pad.Held.Down - Pad.Held.Up;
            u8 baldosa = obtenerBaldosa(x + HEROE_X + 8, y + HEROE_Y + 16);
            baldosa |= obtenerBaldosa(x + HEROE_X, y + HEROE_Y + 16);
            baldosa |= obtenerBaldosa(x + HEROE_X + 8, y + HEROE_Y + 8);
            baldosa |= obtenerBaldosa(x + HEROE_X, y + HEROE_Y + 8);
            //PA_OutputText(SCREEN_BOTTOM, 0, 6, "baldosa: %d      ", baldosa); // para debugear!!
            if (baldosa == ESPACIO_LIBRE) {
                fondoX = x;
                fondoY = y;
                PA_ParallaxScrollXY(SCREEN_TOP, fondoX, fondoY);
            } else {
                estadoAnimacion = ANIMACION_PAUSA;
            }
        }
        PA_WaitForVBL();
    }
    return 0;
}

u8 obtenerBaldosa(s32 x, s32 y) {
    return mapa_Map[((y>>3) * 92) + (x>>3)];
}

void cargarPortadas() {
    PA_EasyBgLoad(SCREEN_TOP, BACKGROUND_ZERO, portada);
    PA_EasyBgLoad(SCREEN_BOTTOM, BACKGROUND_ZERO, subportada);
    bool salir = false;
    while  (!salir) {
        salir = Stylus.Held;
        PA_WaitForVBL();
    }
    u8 i = 0;
    for (i = 0; i < 32; i++) {
        PA_SetBrightness(SCREEN_TOP, -i);
        PA_SetBrightness(SCREEN_BOTTOM, -i);
        PA_WaitForVBL();
    }
    PA_DeleteBg(SCREEN_BOTTOM, BACKGROUND_ZERO);
    PA_DeleteBg(SCREEN_TOP, BACKGROUND_ZERO);
    PA_SetBrightness(SCREEN_TOP, 0);
    PA_SetBrightness(SCREEN_BOTTOM, 0);
    PA_EasyBgLoad(SCREEN_BOTTOM, BACKGROUND_ZERO, portada);
    return;
}


Este juego por ahora lo dejamos acabado.

Saludos y Feliz año.

Enlaces patrocinados:

3 comentarios:

David Martínez Martínez dijo...

Está muy bien como un tutorial. Aprendí mucho con tu blog, muchas gracias. ¿Con qué quieres ponerte ahora? Espero que tengamos más noticias tuyas pronto.

Anónimo dijo...

un remate final muy bueno... lo primero que entra es la portada de un juego, y es muy importante saber como se pone una. sigue con el blog, por favor, que yo seguire aprendiendo. un saludo!

Anónimo dijo...

ojala continues y nos enseñes a crear menus,enemigos,objetos,
juegos tipo mario etc...
MOLARIA