viernes, 18 de septiembre de 2009

La aventura de Mario

Por fin ponemos a Mario en su sitio. Mario se hace dueño y señor de su mundo. Un juego que se llama New Super Mario Bros y que no saliera él por ningún sitio era algo extraño. Pues nada un poco de photoshop para ponerle guapo y ya está. Quitamos a koopa y ponemos a Mario.

Nos ha hecho cambiar alguna cosa más, como por ejemplo el mario_collision_map. Es que este Mario es un poco más bajito que Koopa. También cambia el número de frames que forman la animación (el número de imágenes que representan el movimiento).

El aspecto de nuestro juego DS es el siguient:


Es el Mario pequeñito. Ya pondremos al intermedio, porque el grande es otra historia.

Saludos

viernes, 11 de septiembre de 2009

Instalar DevkitPro en linux - Ubuntu

Hemos instalado devkitpro y PAlib en una distribución de Ubuntu.

Hemos seguido los siguientes pasos:

Hemos descargado de la red los siguientes ficheros:

devkitarm, libNds, DSwifi, libfat de http://sourceforge.net/project/showfiles.php?group_id=114505
y PAlib: http://www.palib.info/wiki/doku.php

Se han descargado en el Escritorio. Abrimos un terminal y ejecutamos los siguientes comandos:

$ cd Escritorio
$ sudo mkdir /usr/local/devkitpro
$ sudo chmod 777 /usr/local/devkitpro
$ sudo bunzip2 devkitARM_r26-i686-linux.tar.bz2
$ sudo tar xvf devkitARM_r26-i686-linux.tar -C /usr/local/devkitpro
$ sudo mkdir /usr/local/devkitpro/libnds
$ sudo chmod 777 /usr/local/devkitpro/libnds
$ sudo bunzip2 libnds-1.3.6.tar.bz2
$ sudo tar xvf libnds-1.3.6.tar -C /usr/local/devkitpro/libnds
$ sudo bunzip2 dswifi-0.3.9.tar.bz2
$ sudo tar xvf dswifi-0.3.9.tar -C /usr/local/devkitpro/libnds
$ sudo bunzip2 libfat-nds-20070127.tar.bz2
$ sudo tar xvf libfat-nds-20070127.tar -C /usr/local/devkitpro/libnds
$ sudo mkdir /usr/local/devkitpro/PAlib
$ sudo chmod 777 /usr/local/devkitpro/PAlib

Aquí me cansé de lanzar tantos comandos y lo que hice fue copiar con el explorador de archivos el
fichero PAlib99999.7z a devkitpro y con el ratón ejecutar descomprimir aquí.

Para acabar lanzamos el siguiente comando:
$ gksudo gedit /etc/environment

y añadimos al final las siguientes líneas:

DEVKITPRO="/usr/local/devkitpro"
DEVKITARM="/usr/local/devkitpro/devkitARM"
PAPATH="/usr/local/devkitpro/PAlib"

Para instalar un emulador realizamos los siguientes pasos:

En el menú principal: Sistema/administración/gestor de paquetes synaptic
buscamos 'Desmume' y lo bajamos. Son dos paquetes.

Y ya está todo.

He creado la carpeta devDS en /home/inigo/devDS (donde inigo es mi usuario) y ahí he copiado el proyecto. Dentro de SuperMarioDS se puede ejecutar (desde el terminal) la sentencia make. Una vez compilado para ejecutarlo escribimos desmume SuperMarioDS.nds y ...



Es Mario y no Koopa!!.....la semana que viene lo vemos.

Saludos

NOTA:
A fecha de Junio de 2010 esta ayuda ya no va bien. Además de los ficheros que se han instalado es necesario bajarse otros más como son maxmod_ns, libfilesystem y default arm7. Todos estos ficheros los hemos instalado en la carpeta libnds.
Os pongo el link a la wiki de devkitpro donde explica todo: http://wiki.devkitpro.org/index.php/Getting_Started/devkitARM

Existe otro forma de instalarlo y es ejecutando un script (devkitpro.sh) que puedes bajar de la página http://lmn.mooo.com/projects/devkitpro-sh/. Este script se pueden modificar las primeras líneas para que no instale lo que no se quiera:
INSTALL_PALIB="yes"
INSTALL_ULIB="yes"
INSTALL_NOCASHGBA="yes"

Se cambia el 'yes' por otra cosa y esa librería o programa no se instala. Te pide tener instalado el 7zr y el unrar. estos se instalan escribiendo en la consola:  sudo apt-get install p7zip y  sudo apt-get install unrar.

Acordarse de dar permisos de ejecución al script:  chmod a+x devkitpro.sh

Aunque todo esto lo explican más o menos en la página web.

viernes, 4 de septiembre de 2009

Nueva versión del entorno de desarrollo

Tenemos nueva versión de devkitPro y parece que muchos de los problemas de instalación han desaparecido. Ya no hace falta cambiar algunas de las librerías que vienen por defecto con el devkitPro para que PAlib funcione.

Pero sí que va a ser necesario cambiar algo de nuestro código. Pero eso lo veremos más adelante.

Ahora mismo los pasos para instalar el entorno de homebrew de la nintendo DS son los siguientes:

Para instalar devkitPro en windows:

1. Bajar devkitPro Updater 1.5.0 de esta dirección.
2. En una de las pantallas nos muestra esta opción 'Download and install/install from downloaded files' la dejamos pulsada y seguimos
3. La siguiente nos preunta que hacer con los ficheros que ha bajado. Por defecto está seleccionada Keep downloaded files, que lo único que hace es dejar todos los ficheros en la carpeta de descargas. Yo lo dejé por si tenía algún problema. Cada uno... Seguimos.
4. Seleccionamos devkitARM -> para trabajar con la DS (la que usamos en este blog)
devkitPPC -> para gamecube/wii
devkitPSP -> para la PSP
2. A la hora de instalarlo Lo instalaremos en c:\devkitPro (Instalarlo donde queráis pero que la ruta no tenga espacios en blanco)
6. Se tirará un ratito bajando e instalando cosas...

Y ya está, ahora le toca el turno a PAlib.

7. Bajamos la última versión (es una beta).
8. Creamos la carpeta c:\devkitPro\PAlib y descomprimimos el zip PAlib090801.7z ahí.

Y ya está todo!!!!.

Ahora un emulador. Yo he bajado no$gba y lo he instalado en C:\devkitPro\emulators\no$gba.

Ahora le toca el turno a nuestro programa, el SuperMarioDS.

Hay que cambiar una serie de cosas en el código, así que crearemos un proyecto nuevo y trasladaremos las cosas del antiguo a este. Lo primero que hacemos es copiar la carpeta C:\devkitPro\PAlib\template a c:\devDS o donde trabajemos. Cambiamos el nombre template por SuperMarioDS y borramos el fichero main.c de source. Yo para hecer esto renombre el antiguo SuperMarioDS por SuperMarioDS_old

Si nos fijamos las carpetas han cambiado un poco. El mayor cambio es la carpeta gfx, que pasa de source a estar al nivel de todas las demás. El programa ha cambiado un poco así que únicamente copiaremos los ficheros PNG a la nueva carpeta. El ini ha cambiado, también, así que lanzamos el programa PAGfxFrontend.exe (se necesita tener instalado .net) y se cargan como sprites lo siguientes ficheros: coin.png, goomba.png y koopa.png
Como backgrounds se cargarán estos otros: fondo_azul.png, newImage_0.png, newImage_1.png

Salvamos y generamos, ningún problema. Sólo que únicamente crea all_gfx.h y NO all_gfx.c. Tendremos que quitar esa referencia.

En el make file hacemos una pequeña modificamos en la línea 46:

Antes: SOURCES := source data gfx/bin
Ahora: SOURCES := source data gfx/bin source/devnintendods

De esta forma podemos usar las fuentes que hay en source/devnintendods.

Ahora el resto de cosas. Los ficheros que estaban en data (dos .raw) siguen en la nueva data.

El fichero devnintendods.h de include se va al nuevo include y source sigue igual quitando el gfx antiguo, claro.

Ahora, si compilamos, saldrán una serie de errores. En mi caso bastantes. Lo primero, quitar all_gfx.c de NSMB.cpp.

Otra cosa, en ScreenManager.cpp cambia la línea 45 y en el .h correspondiente la línea 137:
Lo que antes era:
SetBackground(unsigned int background, int *info, void * pal, const unsigned char *tiles, u32 tiles_size, const unsigned short *mapa)
ahora es:
SetBackground(unsigned int background, int *info, void * pal, const unsigned char *tiles, unsigned int tiles_size, const unsigned int *mapa)

El array Blank, que era un array a blanco ha desaparecido, así que da error la línea 16 del TileSet.cpp, la he comentado. Ahora no se usa, pero...

Y no recuerdo más cambios.

El juego ya compila y se puede ejecutar.

La semana que viene veremos como instalar en ubuntu, que es un poco más largo, pero no da ningún tipo de problema.

Saludos

P.D. Tras el descanso veraniego, en que le blog no ha sido actualizado, vamos a intentar seguir con el blog. No sé de cuanto tiempo dispondré pero bueno...

Enlaces paqtrocinados

viernes, 17 de julio de 2009

Dejamos el salto fino

Hasta ahora a la hora de caer de un salto nuestro personaje realizaba una misteriosa maniobra. Justo antes de caer al suelo frenaba de forma misteriosa. Lo que ocurría era que el código al obtener una colisión con el suelo reseteaba todos los valores del salto y empezaba a caer de nuevo.

Eso hay que cambiarlo.

Lo único que se necesita es que al obtener una colisión, como estamos cayendo con una 'fuerza' de más de un pixel, debemos encontrar la primera posición libre antes de las plataformas. Un sencillo for realizará este trabajo (NSMB.cpp):


bool NSMB::BeforeVBL() {
if (tiempoSalto-- < 0) {

tiempoSalto = MOVIMIENTO_VELOCIDAD_INTERMEDIA;
int y = koopa->GetY();
koopa->SetY(y + fuerzaSalto);
if (topScreen->IsCollision(koopa, topScreen->GetBackgroundsX() / 8, topScreen->GetBackgroundsY() / 8)) {
if (fuerzaSalto > 0) {
int i = 0;
for (i = 0; i < MAXIMA_FUERZA_CAIDA; i++) {
koopa->MoveUp();
if (!topScreen->IsCollision(koopa, topScreen->GetBackgroundsX() / 8, topScreen->GetBackgroundsY() / 8)) break;
}
} else {
koopa->SetY(y);
}
fuerzaSalto = 0;
volando = false;
} else {
if (fuerzaSalto < MAXIMA_FUERZA_CAIDA) fuerzaSalto++;
volando = true;
}
}
return 1;
}


El aspecto del juego no ha cambido demasiado:

Otras cosas que hemos hecho es seguir 'mejorando' la librería. Por ejemplo, las funciones de mover un sprite, MoveLeft, MoveUp que tengan el parámetro opcional y así realizar un movimiento de 1 por defecto, preparando el código para coger las monedas, etc.

Esta semana si vamos a colgar el proyecto, tal cual está.

Saludos

P.D. Otra cosa, estamos en verano y los post no serán tan fluidos, pero supongo que tampoco las visitas.

viernes, 19 de junio de 2009

Mejoramos el movimiento

Todas estas semanas atrás hemos estado programando el juego utilizando las funcionalidades de los Tiles que nos brinda PALib. Esto está muy bien para juegos tipo Tetris, de tablero, etc. Pero para el New Super Mario Bros, o para los Pokemon no es totalmente válido.

El programar con tiles permite dibujar la pantalla con 'azulejos' de 8x8 pixeles, por lo que el movimiento del fondo (necesario en este tipo de juegos) ha de ser de 8 en 8 pixeles y eso no puede ser. Necesitamos unas transiciones más suaves.

PALib permite crear tiles y mover el fondo como de si una imagen se tratara. Así que hemos realizado los siguientes cambios en nuestra librería y en el editor de mapas.

Con respecto a la nueva librería hemos creado nuevas funciones para tratar los fondos. Estas funciones estarán en ScreenManager:


/**
* Asigna una imagen de fondo
*
* @param background Cada pantalla de la consola permite cuatro niveles de
* fondos. Los valores posibles son: BACKGROUND_ZERO, BACKGROUND_ONE,
* BACKGROUND_TWO, BACKGROUND_THREE (de mayor a menor prioridad)
*/
void SetBackground(unsigned int background, int *info, void * pal, const unsigned char *tiles, u32 tiles_size, const unsigned short *mapa);

/**
* Devuelve la coordenada X única a todos los fondos.
*/
int GetBackgroundsX();

/**
* Devuelve la coordenada Y única a todos los fondos.
*/
int GetBackgroundsY();

/**
* Asigna la coordenada X única a todos los fondos.
* Se utiliza para mover todos los fondos a la vez
*
* @param y coordenada x
*/
void SetBackgroundsX(int x);

/**
* Asigna la coordenada Y única a todos los fondos.
* Se utiliza para mover todos los fondos a la vez
*
* @param y coordenada Y
*/
void SetBackgroundsY(int y);

/**
* Asigna las coordenadas X, Y única a todos los fondos.
* Se utiliza para mover todos los fondos a la vez
*
* @param y coordenada x
* @param y coordenada Y
*/
void SetBackgroundsXY(int x, int y);

/**
* Desplaza a la izquierda todos los fondos una cantidad dada
* Se utiliza para mover todos los fondos a la vez
*
* @param offset desplazamiento
* @return la nueva coordenada x
*/
int MoveBackgroundsLeft(int offset);

/**
* Desplaza a la derecha todos los fondos una cantidad dada
* Se utiliza para mover todos los fondos a la vez
*
* @param offset desplazamiento
* @return la nueva coordenada x
*/
int MoveBackgroundsRight(int offset);

/**
* Desplaza arriba todos los fondos una cantidad dada
* Se utiliza para mover todos los fondos a la vez
*
* @param offset desplazamiento
* @return la nueva coordenada y
*/
int MoveBackgroundsUp(int offset);

/**
* Desplaza abajo todos los fondos una cantidad dada
* Se utiliza para mover todos los fondos a la vez
*
* @param offset desplazamiento
* @return la nueva coordenada y
*/
int MoveBackgroundsBottom(int offset);


De esta forma podemos asignar una serie de imágenes a los distintos fondos y moverlos sin problema los pixeles que se desean. En nuestro caso los fondos se moverán de izquierda a derecha.

Las funciones utilizadas hasta hoy, CreateTileSet, y la clase TileSet se dejarán para los proyectos que lo necesiten.

En cuanto al programa de edición de mapas se han cambiado los ficheros de salida. Ahora genera un png con el dibujo que se ha editado. Este dibujo debe pasar por PAGfx para generar los ficheros de salida. A continuación publicamos las dos imágenes de salida del programa de edición:


Fondo cero


Fondo uno

El código en NSMB.cpp quedará así:


topScreen->SetBackground(BACKGROUND_ZERO, FONDO_CERO);
topScreen->SetBackground(BACKGROUND_ONE, FONDO_UNO);
topScreen->SetBackground(BACKGROUND_THREE, FONDO_TRES);
topScreen->SetCollisionMap8x8((void *)newImage_0_Map, newImage_0_Info[1] / 8, newImage_0_Info[2] / 8);


Esta semana no voy a publicar código. Son demasiados cambios de un solo golpe y no puedo mantener bien las versiones. Además de que el código estará lleno de errores.

Ahora mi objetivo es dejar el salto fino y coger las monedas.

Espero tener para la semana que viene cosas nuevas que ofrecer, aunque el verano me va a quitar tiempo.

Saludos

viernes, 12 de junio de 2009

Los sonidos

A partir del post de como programar los sonidos en la Nintendo DS, con el código de David que publicamos hace ya un tiempo, vamos a implementar los sonidos de nuestro juego.

Como ya explicamos en aquel post, las librerías PALib leen los ficheros de audio en formato raw.

Para pasar de mp3 a raw lo he hecho con 'Switch Sound File Converter'. Para editar los ficheros hemos usado Audacity.

Los ficheros de sonido se dejan en la carpeta data de SuperMarioDS.

La Instrucción PA_InitSound la hemos puesto en el constructor de GameManager.cpp. Ahora en la instalación que tengo de PALib ha empezado a dar problemas y he tenido que cambiar el código, que ha quedad de esta forma:


GameManager::GameManager() {
PA_Init();
PA_InitVBL();

//PA_InitSound();
AS_Init(AS_MODE_SURROUND | AS_MODE_16CH );
AS_SetDefaultSettings(AS_PCM_8BIT, 11025, AS_SURROUND);


El código a cambiar en NSMB.cpp es el siguiente:


#include
#include "salto.h"

....

bool NSMB::HeldUp() {
if (!volando) { //Si no estamos volando podremos saltar
//PA_PlaySimpleSound(0, salto);
PA_PlaySimpleSound(salto);
tiempoSalto = TIEMPO_SALTO;
volando = true;
fuerzaSalto = FUERZA_SALTO_INICIAL;
}
return 1;
}

El error que aparecía al compilar era
'PA_InitSound' was not declared in this scope
, y ahí me he quedado, he cambiado PA_InitSound y PA_PlaySimpleSound(0, salto) por las otras instrucciones y ya funciona (¿?¿?¿?¿?).

Ahora habrá que ir poniendo sonidos a las distintas acciones...

Saludos

viernes, 5 de junio de 2009

La gravedad y el salto

Bueno, aquí no vamos a explicar lo que es la gravedad, pero si que es necesario ponerla en nuestro juego.

Vamos a programar la gravedad en nuestro juego.

El tema está en que al saltar, Mario no sube y después baja, no....si no que al saltar Mario sube, el bajar es cosa de la gravedad, no del salto. Por lo que habrá que programar primero el tema de la gravedad.

Lo primero será hacer un mapa con una zona elevada y poner ahí a nuestro héroe. Y que al salir de dicha zona la gravedad le haga caer y que lo haga hasta que ocurra una colisión.

he creado varias variables, una para saber que estamos cayendo, ya que en esos momentos no podemos saltar. Sólo se salta desde el suelo.
Otra es para el tema de la fuerza al caer, es decir, cada vez se cae más deprisa y el retardo del salto para que no caiga demasiado deprisa.


bool NSMB::BeforeVBL() {
if (tiempoSalto-- < 0) {
tiempoSalto = MOVIMIENTO_VELOCIDAD;
int y = koopa->GetY();
koopa->SetY(y + fuerzaSalto);
if (topScreen->IsCollision(koopa, mundo_plataformas_cero->GetX(), mundo_plataformas_cero->GetY())) {
koopa->SetY(y);
fuerzaSalto = 1;//inicializar
volando = false;
} else {
if (fuerzaSalto < MAXIMA_FUERZA_CAIDA) fuerzaSalto++;
volando = true;
}
}
return 1;
}


El código lo hemos colocado en la función BeforeVBL que se ejecuta en cada vuelta del bucle y antes del refresco de la pantalla. Esto se ha hecho así porque la gravedad actua continuamente.

Lo que realmente hace nuestro código es coger la coordenada 'Y' de nuestro héroe y sumarle la fuerza. La hemos llamado fuerzaSalto porque sirve igualmente para saltar que para caer, ya hemos dicho que saltar y caer es lo mismo.

Una vez sumados los valores vemos si hay colisión, si no es el caso aumentamos la fuerza, cada vez caemos más fuerte (hasta un límite 'MAXIMA_FUERZA_CAIDA'). Este algoritmo se ejecutará hasta llegar a un suelo.

Y ahora que pasa si fuerzaSalto es negativo. Pues que tenemos a nuestro héroe saltando. Por lo que necesitamos este código para comenzar a saltar:


bool NSMB::HeldUp() {
if (!volando) { //Si no estamos volando podremos saltar
tiempoSalto = TIEMPO_SALTO;
volando = true;
fuerzaSalto = FUERZA_SALTO_INICIAL;
}
return 1;
}


Y ya está, programando la gravedad nos ha salido gratis el salto. Así da gusto!

El juego tiene este aspecto ahora mismo:


Aún así queda un efecto feo al aterrizar. Ya lo trabajaremos más adelate.

Ahora sólo queda coger las monedas, meter los sonidos, los efectos de fondo, más plataformas,... esto no acaba nunca.

Saludos, nos vemos en los comentarios.