Lo primero, si vemos el código, es que apenas hay nada de PALib en el código. Sólo está el include y un par de constantes. Las clases han conseguido encapsular todo el código PALib.
Veamos el código del programa:
NSMB::NSMB() {
gameManager = new GameManager();
gameManager->SetKeypadManager(this);
topScreen = gameManager->GetTopScreenManager();
koopa = topScreen->CreateSprite(BACKGROUND_THREE, KOOPA, 16, 0, 1);
koopa->SetAnim(0, 15, 15);
tileSet = topScreen->CreateTileSet(BACKGROUND_TWO, PLATAFORMAS);
topScreen->PrintMap(MAPA_PLATAFORMAS, tileSet, x, y);
}
Parece poco código, veamos lo que hace:
gameManager = new GameManager();: Es la clase que crea el motor del juego. Podemos decir que engloba el HelloWorld de PaLib, es decir los init y el bucle principal.
gameManager->SetKeypadManager(this);: En esta línea le estamos diciendo que clase va a recibir la información de entrada del juego (el teclado y el sylus). 'this' significa que será la propia clase NSMB la que los recibirá.
Esto es una aproximación a lo que se suele llamar programación orientada a eventos. Es decir, cuando el usuario pulse un botón de la consola, NSMB recibirá una llamada a una de las funciones que tiene que implementar. Si, por ejemplo, se pulsa el botón de A se lanzará la función NewpressA.
Sería algo parecido a los callback, pero más orientado a objetos.
topScreen = gameManager->GetTopScreenManager();: Esto es una forma de tener una variable que apunte a la pantalla superior y no tener que ir todo el rato arrastrándo gameManager->GetTopScreenManager().
topScreen->CreateSprite(BACKGROUND_THREE, KOOPA, 16, 0, 1);: Ya tenemos un sprite hecho. Más fácil imposible. Los parámetros último son x, y y si lo queremos girar horizontalmente (1 = si).
koopa->SetAnim(0, 15, 15);: Y ahora lo animamos, entre los frames 0 a 15 y la velocidad es de 15.
tileSet = topScreen->CreateTileSet(BACKGROUND_TWO, PLATAFORMAS);: Creamos los tileset (serían los ladrillos de nuestro juego) para los fondos.
topScreen->PrintMap(MAPA_PLATAFORMAS, tileSet, x, y);: Y dibujamos el fondo de la pantalla superior.
Ya está...........
No parece muy complicado. Si no se tiene mucha experiencia en la programación con PALib puede resultar rara la definición de KOOPA. Pues nada, con echar un ojo a la entrada que se hizo en su día explicando los Sprites creo que será suficiente.
Por ahora estamos trabajando con Koopa como personaje. En cuanto saque tiempo prepararé los sprites de Mario.
El resto del código es:
void NSMB::Run() {
gameManager->Run();
}
Se podía haber puesto en el constructor (NSMB::NSMB()) pero aquí parece que queda mejor.
bool NSMB::HeldLeft() {
if (movimiento != MOVIMIENTO_IZQUIERDA) {
koopa->Hflip(0);
movimiento = MOVIMIENTO_IZQUIERDA;
koopa->StartAnim();
} else {
koopa->RestartAnim();
}
velocidad--;
if (velocidad == 0){
velocidad = MOVIMIENTO_VELOCIDAD;
x--;
}
return 1;
}
Cuando el jugador pulse en el botón de flecha izquierda se ejecutará este código, que ahora mismo únicamente, anima a nuestra tortuga. Usa la variable 'movimiento' para hacerlo una animación más fluida, y girar a nuestro héroe cuando sea necesario. Falta el tema de las colisiones.
Con más detalle: si la tortuga estaba con otra orientación (if (movimiento != MOVIMIENTO_IZQUIERDA)) no hace falta girarlo (Hflip(0) = lo desgiramos - el sprite original mira a la izquierda) y empezamos la animación. Si ya estábamos mirando a la izquierda, únicamente, continuamos con la animación (RestartAnim). El resto del código es para ir poco a poco (lo intentaremos mejorar llamando a una función, que también la llamará HeldRight, que será la encargada de mover a nuestro héroe y mirar las colisiones).
bool NSMB::HeldRight() {
if (movimiento != MOVIMIENTO_DERECHA) {
koopa->Hflip(1);
movimiento = MOVIMIENTO_DERECHA;
koopa->StartAnim();
} else {
koopa->RestartAnim();
}
velocidad--;
if (velocidad == 0){
velocidad = MOVIMIENTO_VELOCIDAD;
x++;
}
return 1;
}
Igual que el anterior pero para ir a la derecha.
bool NSMB::NoKey() {
koopa->PauseAnim();
return 1;
}
Si no se ha pulsado ninguna tecla se ejecutará esta función. Nosotros la usaremos para parar la animación de nuestro héroe.
bool NSMB::BeforeVBL() {
topScreen->PrintMap(MAPA_PLATAFORMAS, tileSet, x, y);
return 1;
}
Esto se ejecutará siempre, una vez por cada vuelta del bucle, después de tratar el teclado (incluida la función de que no se ha pulsado ninguna tecla).
Y esto es todo, por ahora. La primera versión de GameManager ha sido publicada, esperemos que no sea la última.
Y ¿cómo usarlo? Es decir, ¿cómo llamar a NSMB?
Vemos el código de main.cpp:
#include "NSMB.h"
int main(int argc, char ** argv) {
NSMB *nsmb = new NSMB();
nsmb->Run();
return 0;
}
Uhmmm, no sé que se puede explicar. Se crea un objeto de tipo NSMB y ejecutamos un 'run'.
Nos vemos en los comentarios.
Saludos