viernes, 20 de noviembre de 2009

Cargamos las monedas

Vamos a cargar las monedas en el mundo de New Super Mario Bros, y para hacer esto utilizaremos el programa que nos genera los mapas.

Se ha agregado una nueva opción al generador de mapas para que permita editar una capa denominada coins (monedas). En la siguinete imagen se puede ver al editor a pleno rendimiento:


El editor al guardar generará un nuevo fichero que se llamará coins_mapa_8_nombre del txt) y coins_mapa_16_nombre del txt). Este último será el que utilizaremos.

ahora veamos los cambios en el código del juego.

En primer lugar seguimos añadiendo funcionalidades a las librerías:
En la clase ScreenManager.h se ha añadido una función para cargar sprites de fondo a partir de una array (el que genera el editor de mapas):

/**
* Carga una serie de sprites de tipo background a partir de un mapa y de un primer sprite de tipo background
* ya cargado.
* Este primwr sprite será reubicado a la priemra posición indicada por el mapa.
*
* @param sprite El sprite a cargar
* @param map mapa que indica donde colocar cada sprite
* @param mapCols número de columnas del mapa
*/
void LoadBackgroundSprites(Sprite *sprite, int *map, int map_columns, int map_rows);


En ScreenManager.cpp hemos codificado la funcion de la siguiente forma:


void ScreenManager::LoadBackgroundSprites(Sprite *sprite, int *map, int map_columns, int map_rows) {
unsigned int i;
unsigned int length = map_columns * map_rows;
bool primero = true;
for (i = 0; i < length; i++)
if (map[i] > 0) {
int y = i / map_columns;
int x = i - (y * map_columns);
if (primero) {
sprite->SetXY(x * 16, y * 16);
primero = false;
} else CloneBackgroundSprite(sprite, x * 16, y * 16);
}
}

Lo que hace esta función es coger un sprite de fondo y un array y donde el array le indique coloca un copia del sprite de fondo, que en este caso serán modenas.

Vamos a ver como se usa esta nueva función en nuestro juego:


int coins_map[48 * 12] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 56, 0, 56, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#define COINS_MAPA coins_map, 48, 12

....

Sprite *coin = topScreen->CreateBackgroundSprite(BACKGROUND_THREE, COIN, 0, 0);
coin->SetAnim(0, 3, 4);
coin->StartAnim();
topScreen->LoadBackgroundSprites(coin, COINS_MAPA);


La explicación sería algo así:
Carga una primera moneda (las coordenadas dan igual, en este caso se ha puesto 0, 0),
Se anima el sprite,
y finalmente se cargan tantas monedas como diga el mapa.

Los números que aparecen en el mapa no es importante (por ahora). Sólo es importante que sea cero donde no va moneda y distinto de cero donde queremos una moneda.

Nos falta coger las dichosas monedas!!

En el próximo post intentaremos cogerlas y de paso publicaremos código.

Saludos

viernes, 13 de noviembre de 2009

Programar para la Wii

Ya desde el primer post teníamos intención de programar algo para la Wii, y no ha sido hasta el pasado mes de Octubre que tuvimos un par de tardes libre y pudimos hacer las primeras pruebas.

En este post vamos a mostrar como preparar la instalación de devkitpro para poder compilar juegos para la Wii. En su día preparamos una instalación sobre ubuntu y ahora vamos a hacer que esa misma instalación soporte a la Wii, y a la Game Cube que es lo mismo.

En resumen podemos decir que es lo mismo que el otro día pero instalando las librerías libogc en vez de libnds. Vamos a ver paso a paso:

Lo primero será bajar todo lo necesario:

Bajar devkitPPC de http://sourceforge.net/projects/devkitpro/files/ (si no lo tenemos instalado ya)
libogc -> http://sourceforge.net/projects/devkitpro/files/libogc/ (libogc-1.7.1.tar.bz2)
libfat-ogc -> http://sourceforge.net/projects/devkitpro/files/libfat/ (libfat-ogc-1.0.4.tar.bz2)
Wii examples (optional) -> http://sourceforge.net/projects/devkitpro/files/examples/ (wii-examples-20090509.tar.bz2)

En segundo lugar todos estos comandos:
$ cd Escritorio

(Si no tenemos instalado devkitpro)
$ sudo mkdir /usr/local/devkitpro 'si ni existiera ya
$ sudo chmod 777 /usr/local/devkitpro 'si ni existiera ya
$ sudo bunzip2 devkitARM_r26-i686-linux.tar.bz2
$ sudo tar xvf devkitARM_r26-i686-linux.tar -C /usr/local/devkitpro

(Seguimos)
$ sudo bunzip2 devkitPPC_r17-i686-linux.tar.bz2
$ sudo tar xvf devkitPPC_r17-i686-linux.tar -C /usr/local/devkitpro
$ sudo mkdir /usr/local/devkitpro/libogc
$ sudo chmod 777 /usr/local/devkitpro/libogc
$ sudo bunzip2 libogc-1.7.1.tar.bz2
$ sudo tar xvf libogc-1.7.1.tar -C /usr/local/devkitpro/libogc
$ sudo bunzip2 libfat-ogc-1.0.4.tar.bz2
$ sudo tar xvf libfat-ogc-1.0.4.tar -C /usr/local/devkitpro/libogc

Ahora añadimos unas variables de contexto:

$ gksudo gedit /etc/environment

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

DEVKITPRO="/usr/local/devkitpro"
DEVKITARM="/usr/local/devkitpro/devkitARM"
DEVKITPPC="/usr/local/devkitpro/devkitPPC"

Reiniciando la máquina ya podremos compilar los ejemplos.

Instalar libwiisprite:

Descargar de http://chaosteil.googlepages.com/libwiisprite-0.3.0b.tar.gz

Lo descomprimos en el mismo lugar donde lo descargamos y realizamos los siguientes pasos:

De la carpeta libwiisprite/libwiisprite/include copiamos todos los archivos a /usr/local/devkitpro/libogc/include
(en mi caso he ejecutado la siguiente acción desde un terminal: sudo cp /home/inigo/Escritorio/libwiisprite/libwiisprite/include/*.h /usr/local/devkitpro/libogc/include)
Ahora sudo cp /home/inigo/Escritorio/libwiisprite/libwiisprite/lib/*.a /usr/local/devkitpro/libogc/lib/wii

Lo mismo con la carpeta libwiisprite/libpng:
sudo cp /home/inigo/Escritorio/libwiisprite/libpng/include/*.h /usr/local/devkitpro/libogc/include
sudo cp /home/inigo/Escritorio/libwiisprite/libpng/lib/*.a /usr/local/devkitpro/libogc/lib/wii

Yo en este punto tuve un problema con libwiisprite y realicé los siguientes pasos:

Bajar una nueva compilación de http://www.mediafire.com/download.php?wwycxmg0j0x
y ejecutar: sudo cp /home/inigo/Escritorio/libwiisprite.a /usr/local/devkitpro/libogc/lib/wii

Descargar con Synaptic la librería libfreeimage

Si todo ha ido bien ya se podrá compilar los ejemplos que vienen con la librería.

Hemos instalado la librería libwiisprite, hay más librerías pero nosotros sólo vamos a usar esta, por ahora.

Y que vamos a hacer nosotros en este blog, pues algo muy sencillo, vamos a pasar el Tetris que hicimos para la DS a la Wii!!!

Para ir abriendo boca os dejo un video para que veáis como ha quedado el juego, si os fijaís bien es el mismo que el de la nintendo DS (sólo hemos cambiado el fondo).


Saludos

P.D. En los siguientes post sobre Wii veremos como trabajo con ella, pero lo que no puedo explicar bien es como crear el Homebrew channel. Lo hice hace un año y ahora hay nuevas formas de hacerlo y no tengo ni idea.

P.D. Seguimos con el tema del New Super Mario Bros. El próximo post será para él.

martes, 10 de noviembre de 2009

Retomamos

Ha habido un cierre temporal del blog estos meses, que espero que sea eso, temporal.

Como penitencia voy a crear unos post hablando de la Wii y de como programar para ella. Ya tengo portado el tetris (por ahora usando el mando como un pad) y no hemos pasado el New Super Mario Bros, porque lo van a hacer los de Nintendo este mes y no era cuestión de adelantarnos a ellos :D

Por supuesto, seguiremos con el New Super Mario Bros para la Nintendo DS.

Este viernes posteamos fijo!!!

Saludos

P.D. Hemos cambiado el título del blog, ahora es Programar para la Nintendo DS y Wii, la url por supuesto sigue igual!!

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.