viernes, 27 de febrero de 2009

New Super Mario Bros

¡Cómo programar un juego tipo New Super Mario Bros (NSMB)!

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);


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

7 comentarios:

David Martínez Martínez dijo...

Ya lo puse y lo probé, no tuve ningún problema al compilar. Por cierto, ¿por qué no usas el directorio include para poner todas tus librerías? Que menos que el devnintendods.h.

Ah, y otra cosa. La carpeta no tiene archivo de proyecto de programmer's notepad, ¿que editor usas? Simple curiosidad.

Especial mención para el gráfico del koopa, ¡¡¡dios cuanto frame!!! ¡La verdad no me lo esperaba que fuera tan ENORME el gráfico con las animaciones! xD

Me gusta lo que estás haciendo, aunque la verdad no entiendo muy bien el código, pero para eso está google y tutoriales de C++. Tu dedícate a sacarle las tripas a PAlib, no vas a dárnoslo todo mascado ¡¡Sigue así!!

Inigo dijo...

Buenas David, gracias por los comentarios.

Es cierto que koopa ocupa demasiado, estoy pensando en dejarlo en la mitad de frames. Por ahora lo he dejado porque la calidad de la animación es muy buena.

En el póximo post pondré la versión más actual de Sprite.cpp y una explicación mejor. Cualquier cosa lo preguntaís. Yo también estoy aprendiendo haciendo esto!!

Estoy pensando en dividir este tutorial en dos, por un lado como usar las clases y por otro uno de las clases mismas. Es decir, no son un conjunto de clases para hacer el NSMB, si no para cualquier otro juego.

En cuanto al editor, uso el EditPlus 2, y para compilar ejecuto el .bat desde el explorado de archivos, jejejeje parece un poco cutre!!

David Martínez Martínez dijo...

Bien, vamos por partes.

Hay una máxima en la informática, y en muchas otras areas también. Si funciona, ¡no lo toques! El koopa se ve de muerte así, que tenga muchos frames te tiene que dar igual, ya que tendrás una función que te manipula eso, por lo que no es grave.

Luego, lo de dividir el tutorial en dos, una parte para explicar clases y otra para las clases en sí, me parece perfecto la verdad. Pero como ya dije antes, quien quiera aprender a programar en C++, hay multitud de tutoriales buenísimos por ahí, pero tutoriales con lo que tu estás haciendo, no los hay. Ni siquiera en inglés, que hay cuatro cosas y encima, sin explicar nada de nada. Por lo que, aunque para mi es más fácil que dividas en dos, lo mejor es que expliques solo PAlib, ya que así explicas más y más rápido de lo que es realmente interesante :D

Y sí, eres un poco cutre xD Te recomiendo el programmers notepad, que incluso pulsando alt + 1 te compila el archivo, cosa mucho más rápida que tener que ir al explorador y ejecutar el build.bat. Incluso le puedes configurar que con otra combinación de botones, te ejecute un emulador usando el archivo que tengas abierto. Échale un vistazo, a ver si te gusta.

¡Saludos!

Inigo dijo...

:D Iremos paso a paso.

Me parece interesante lo que dices de utilizar la carpeta include, pero no lo he hecho nunca. ¿Me puedes echar una mano? ¿Cómo cambian mis includes?
Quizás todo el montaje que estoy preparando se pueda ir a esa carpeta.

Muchas gracias, nos vemos!!

David Martínez Martínez dijo...

Pues es muy fácil. Simplemente, copia las librerías que vayas a usar en más de un proyecto en include, no en source. Ya está.

Yo ahí tengo un fichero constantes.h, donde tengo SCREEN_TOP, SCREEN_BOTTOM... Y luego, también tengo funciones de PAlib, como iniciarPAlib y cosas así, en un funcionesGraficas.h. Lo demás que tengo es demasiado específico, por lo que ya lo tengo en source. Los ficheros de include los tengo en la plantilla, en template.

Échale un vistazo, ya verás que es simplemente cortar y pegar. ¡Saludos!

Jose Manuel dijo...

Me Das El Archivo Del Que Contiene Todo El Juego Porfa

Inigo dijo...

Lo tienes al final de los post sobre el juego de Mario Bross.