Pues no es muy difícil, pero tampoco es fácil. Ante la cantidad de elementos que intervienen en el juego yo me inclinaría más por programar con orientación a objetos. Por lo que se necesita un poco más de nivel de programación del que hemos empleado hasta ahora.
Pero no nos desanimemos, utilizaremos la orientación a objetos de una forma sencilla y didáctica y, seguramente, tomaremos decisiones para que resulte lo más sencillo posible.
Otra cosa, en algún comentario se apunta a la posibilidad de hacer pantallas desde donde se puedan elegir opciones, y de esta forma, dejar un acabado más elegante a los juegos. El problema para mi estriba en que todo lleva tiempo y el poco de que dispongo me gusta más emplearlo en hacer el motor propio del juego. Aún así, intentaremos hacer cosas en ese sentido.
Empecemos con con la Orientación a objetos.
A la hora de ir a compilar un fichero .cpp (c++) PALib puede que de algún que otro error de compilación. En mi caso esta fue la pantalla del error:
La solución fue poner lo siguiente en el fichero PA_Sound.h:
línea 212: FS_wav[PA_Channel] = (u32*)PA_Malloc(FS_wav[PA_Channel], PA_FSFile[PAFS_wav_number].Length+4);
línea 430: FS_mod = (u32*)PA_Malloc(FS_mod, PA_FSFile[PAFS_mod_number].Length+4);
Antes de hacer este cambio mirar si os da error al compilar c++.
Y ahora ¿Qué es la orientación a objetos?
Pues es una forma de describir el mundo que estamos programando. Por ejemplo, en el primer tutorial de este blog presentamos un juego muy sencillo, un sprite moviéndose por un pueblecito. En este caso sólo era necesario las coordenadas de nuestro héroe y el mapa para las colisiones. Todo esto era lo único necesario para describir nuestro mundo.
En el Tetris las cosas se complicaban un poco más, teníamos un tablero y unas fichas que giraban. Para describir ese mundo tendríamos dos clases, la del tablero y la de ficha.
Ahora tenemos el NSMB, donde todo es mucho más complejo, no sólo en cantidad, si no en la forma de interactuar entre los distintos elementos del juego, los enemigos, las plataformas, las monedas, incluso nuestro héroe, Mario, puede cambiar de tamaño, salta, etc.
La orientación a objetos permite describir cada parte de nuestro mundo en un fichero aparte, teniendo todo muy bien organizado. Nos permitirá tener personajes con distinto comportamiento moviéndose por el juego. Incluso las propias plataformas serán una clase, desde donde se describirá su aspecto, así como su comportamiento.
Algunas de las clases que presentaremos podrían pasar perfectamente a un proyecto que se denominase PALib++, pero eso ya es harina de otro costal.
Podéis acceder a un primer proyecto para probar el compilador de c++. Esto el lo que se verá si ponéis en marcha el proyecto:
Este código contiene una clase llamada Sprite (en sprite.h está la definición de la clase y en Sprite.cpp el código) que es la responsable de cargar un sprite en la pantalla. Es mejorable, repite paletas y se puede simplificar, aún más, su utilización, pero lo dejaremos para el siguiente post.
Una de las mejoras que nos da el uso de clases es el poder simplificar el algoritmo propio del juego. Main.cpp queda más sencillo, y eso mejora la legibilidad del código. Por ejemplo, si quiero añadir un nuevo Sprite, únicamente serían dos líneas de código.
//Con clases
Sprite koopa(SCREEN_TOP, BACKGROUND_THREE, OBJ_SIZE_32X32, (void*)koopa_Pal, (void*)koopa_Sprite, 128, 140);
koopa.rotar_horizontal();
koopa.animar(0, 15, 15);
//Sin clases
PA_LoadSpritePal(SCREEN_TOP, KOOPA_PALLETE,(void*)koopa_Pal);
PA_CreateSprite(SCREEN_TOP, KOOPA_SPRITE, (void*)koopa_Sprite, OBJ_SIZE_32X32, COLOR_MODE_256, KOOPA_PALLETE, 128, 140);
PA_SetSpritePrio(SCREEN_TOP, KOOPA_SPRITE, BACKGROUND_THREE);
PA_SetSpriteHflip(SCREEN_TOP, KOOPA_SPRITE, 1);
PA_StartSpriteAnim(SCREEN_TOP, KOOPA_SPRITE, 0, 15, 15);
Sprite koopa(SCREEN_TOP, BACKGROUND_THREE, OBJ_SIZE_32X32, (void*)koopa_Pal, (void*)koopa_Sprite, 128, 140);
koopa.rotar_horizontal();
koopa.animar(0, 15, 15);
//Sin clases
PA_LoadSpritePal(SCREEN_TOP, KOOPA_PALLETE,(void*)koopa_Pal);
PA_CreateSprite(SCREEN_TOP, KOOPA_SPRITE, (void*)koopa_Sprite, OBJ_SIZE_32X32, COLOR_MODE_256, KOOPA_PALLETE, 128, 140);
PA_SetSpritePrio(SCREEN_TOP, KOOPA_SPRITE, BACKGROUND_THREE);
PA_SetSpriteHflip(SCREEN_TOP, KOOPA_SPRITE, 1);
PA_StartSpriteAnim(SCREEN_TOP, KOOPA_SPRITE, 0, 15, 15);
En las siguientes entregas iremos mejorando la clase Sprite. Estoy pensando en hacerla en Inglés para que se pueda distinguir bien del algoritmo del juego.
Saludos