Si me habéis seguido hasta aquí y seguís queriendo más después del árido tercer tutorial, es que de verdad disfrutáis con esto de la programación. Y es que es realmente gratificante ver como esa idea que ha partido de nuestra mente, se ejecuta en nuestra querida consola. Después de tres tutoriales hay un periférico que todavía no hemos tocado, y que es realmente interesante e innovador. Este es la Wii Balance Board. En este tutorial te enseñare como usar esta fantástica plataforma.
¿Que es la balance board?, Esa curiosa plataforma que es capaz de detectar nuestro centro de gravedad y nos ayuda a hacer ejercicios o a esquiar en nuestro juego favorito.
Y seguro que muchos de vosotros os habéis preguntado en qué consiste la Balance Board. Pues es más simple de lo que podíamos imaginar. Se trata simple y llanamente de una báscula con una célula de carga en cada una de sus esquinas. Y lo realmente novedoso del tema es que Nintendo ha convertido una simple báscula en un mando de juegos. Pero ¿Cómo se puede utilizar una báscula de esa manera? Pues la clave está en el cálculo del centro de gravedad. Cuando nos subimos a nuestra querida tabla, nuestro peso se reparte por toda ella y cada una las células de carga que posee soporta un peso que sumado da el total de lo que pesamos.
Si fuéramos capaces de equilibrar nuestro peso de tal manera que nuestro centro de gravedad quedara exactamente en el centro de la tabla, las cuatro celdas detectarían el mismo peso, pero si desplazamos nuestro peso hacia alguno de los lados, el peso soportado por cada célula variará. Esto último es lo que nos va a permitir calcular la posición del centro de gravedad triangulando la información del peso. Al saber la posición de ese centro de gravedad tendremos la información de hacia donde tenemos desplazado el cuerpo, y por tanto podremos intuir hacia donde estamos dirigiendo nuestros esquíes en el juego, o nuestra correcta posición en el ejercicio de Yoga.
En la foto anterior podéis ver donde van situadas las células de carga que coinciden exactamente con la posición de las cuatro patas de la tabla.
A lo largo del presente tutorial voy a intentar explicaros paso a paso el desarrollo de una aplicación que haga uso de la Balance board. Y qué mejor aplicación para aprender que realizar una báscula electrónica que además muestre nuestro centro de gravedad.
Y para hacerlo un poquito más estético, utilizaré el tutorial como excusa para explicar un poco más en detalle las librerías de sonido y explicar alguna cosa más de las GX, con lo que al final nos quedará una bonita báscula parlante que leerá nuestro peso en voz alta.
Pues nada, no perdamos más tiempo y vamos al tajo…..
A modo de referencia y sin pretender asustaros, ya que no lo vamos a necesitar para realizar nuestro programa, voy a daros unos breves datos de cómo almacena internamente la información la BalanceBoard.
El formato de datos usado por la Balanceboard consiste en dos partes:
DATOS DE PESO (Gracias a Wiibrew por la información):
DATOS DE CALIBRACION
El peso en cada sensor se calcula interpolando el valor devuelto por dicho sensor con las dos medidas entre las que cae dicho valor.
Para homogeneizar el uso de los mandos y poder usar las mismas funciones que con el wiimote, en la librería WPAD se ha considerado la Balanceboard como si fuera una extensión de un wiimote adicional imaginario conectado a nuestra Wii, de tal forma que la información de la misma viene en el campo “exp” de la estructura de datos de un WPAD.
_wpad_data { s16 err; u32 data_present; u8 battery_level; u32 btns_h; u32 btns_l; u32 btns_d; u32 btns_u; struct ir_t ir; struct vec3w_t accel; struct orient_t orient; struct gforce_t gforce; struct expansion_t exp; // Aquí } WPADData;
Cuando buscamos los wiimotes disponibles con la función WPAD_Probe(), la manera de saber si se trata de una BalanceBoard es comprobar que el tipo de extensión devuelto por dicha función es “WPAD_EXP_WIIBOARD”.
Podríamos utilizar por tanto las siguientes líneas de código para buscar la Balanceboard:
ret = WPAD_Probe(i,&devtype); if ((ret==WPAD_ERR_NONE) && (devtype==WPAD_EXP_WIIBOARD)) printf(‘Balanceboard encontrada’);
Una vez hemos comprobado que tenemos conectada la balanceboard debemos leer los datos que nos devuelve la misma.
La estructura de datos que utilizaremos refleja aproximadamente la que mostrábamos en la sección anterior, pero aquí además tendremos tanto los valores de peso en “bruto” como los valores interpolados, además de los valores de calibración y el centro de gravedad ya calculado:
typedef struct wii_board_t { /* valores interpolados */ float tl; // arriba a la izquierda float tr; // arriba a la derecha float bl; // abajo a la izquierda float br; // abajo a la derecha /* valores en bruto*/ short rtl; // arriba a la izquierda short rtr; // arriba a la derecha short rbl; // abajo a la izquierda short rbr; // abajo a la derecha ´ /* valores de calibración */ short ctl[3]; short ctr[3]; short cbl[3]; short cbr[3]; /* centro de gravedad */ float x; float y; } wii_board_t;
Nosotros realmente solo necesitaremos los datos de peso interpolados y las coordenadas del centro de gravedad.
Para leer dicha información lo podemos hacer como si de un wiimote cualquiera se tratara con la función WPAD_Expansion:
WPAD_Expansion(wbb, &exp);
Y una vez leída la información, podemos fácilmente calcular el peso total sumando los valores de las cuatro esquinas, mientras que el centro de gravedad lo podemos usar directamente:
x=exp.wb.x; y=exp.wb.y; weight=exp.wb.tl+exp.wb.tr+exp.wb.bl+exp.wb.br; // Peso en Kg
Para la creación de la aplicación empezaré describiendo paso a paso la secuencia de desarrollo que deberíamos seguir:
Para editar todos los gráficos que utilizaremos en nuestro programa utilizaremos Paint.Net (recomendado al principio) o el que desees.
Para simplificar el proceso de programación, todos los gráficos que utilizaremos los juntaremos en un solo archivo “.PNG” del cual extraeremos la textura para cada objeto según nos interese.
El gráfico resultante quedaría como sigue:
Para enlazar dicho archivo en nuestro código utilizaremos en mismo método que en el tutorial anterior. Es decir, las librerías TPL.
Como dijimos en el tutorial anterior, necesitaremos un archivo llamados “textures.scf” en el que indicaremos la forma de carga del gráfico. El contenido de dicho archivo quedaría como sigue:
<filepath="wbb.png" id="texturas" colfmt=6 />
Aquí le indicamos que el archivo a enlazar se llama wbb.png y que debe crear una variable llamada texturas, además indica que utilizamos el formato 6 que nos permite la utilización del canal Alfa.
Copiaremos todo lo anterior en la subcarpeta Textures con lo que ya tendremos todo el trabajo de gráficos terminado.
Para la creación de los sonidos utilizaremos el programa Audacity, que nos permite realizar una grabación de nuestra voz, modificarla fácilmente, y conseguir un efecto muy parecido a la clásica voz que Nintendo usa para la Balance Board en el programa WiiFit.
Como en el caso del Paint.Net os he dejado un enlace a la página web del programa al principio del tutorial.
Lo primero que debéis saber es que el formato que utilizaremos en el programa es RAW de 8 bits con signo ya que es el tipo de sonidos soportado por las librerías ASND y para que el tamaño del ejecutable final no sea más grande de lo necesario, utilizaremos una frecuencia de muestreo de 8000Hz,.
Para configurar estos parámetros seguiremos los siguientes pasos dentro del programa.
Seleccionaremos “Editar/Preferencias”.
Y en la pestaña formato de archivo seleccionaremos como formato de
exportación “Otro…”
Tras lo cual nos aparecerá una ventana que nos
permitirá seleccionar una serie de formatos adicionales. Nosotros
seleccionaremos “RAW Signed 8 bits PCM”.
Además de esto seleccionaremos en la pestaña calidad la frecuencia de muestro predeterminada con 8000Hz para hacerla coincidir con el formato que utilizaremos después en la exportación.
Grabando y modificando los sonidos:
Una vez configurado el programa, deberemos grabar todas las combinaciones de sonidos necesarias para poder leer el peso.
Si ponemos el límite de peso en 299 Kg necesitaremos los siguientes sonidos:
A partir de ahí los números son iguales a los números 1 a 99 pero ante-poniendo el sonido “ciento”.
Y por último necesitaremos el sonido “doscientos”.
Necesitaremos por tanto grabar cada uno de los sonidos anteriores
Y después realizar las siguientes modificaciones:
Ambas opciones son accesibles en el menú “Efecto”.
Una vez tengamos grabado y modificado nuestro sonido deberemos exportarlo a formato RAW. Para ello seleccionaremos “Exportar RAW” en el menú de archivo. Repetiremos el proceso para todos los sonidos necesarios.
Ahora que ya tenemos los sonidos en formato RAW se nos plantea el problema de cómo utilizarlos en nuestro programa.
Para ello utilizaremos una utilidad que viene con el devkitpro que se llama raw2c.exe (situada en “\devkitpro\devkitppc\bin”.
Esta utilidad convierte un fichero en formato RAW a un fichero “.c” con todos los bytes del archivo asignados a un array con el mismo nombre que el archivo origen. De esta manera, podremos disponer de nuestro sonido accediendo directamente a dicho array. El formato de utilización es muy sencillo, solo deberemos pasarle el nombre del archivo a traducir y él generará dos archivos, uno con extensión “.c” y otro con extensión “.h” para que podamos incluirlo en nuestro programa.
Ejemplo:
Raw2c uno.raw
Bueno, pues ya lo tenemos todo preparado para empezar con el programa.
La estructura general del programa es similar a la del tutorial anterior, introduciendo algunas particularidades.
El primer problema que nos vamos a encontrar para implementar este proceso es la gestión de sonidos ya que cuando mandamos un sonido nuevo a la librería de sonidos, cualquier sonido anterior que estuviera sonando deja de sonar para comenzar a sonar el nuevo sonido. Por otro lado, no podemos parar la ejecución del programa para esperar a que termine de sonar el sonido en curso, por lo que necesitamos una solución que permita esperarnos y continuar con la ejecución del programa en paralelo.
La solución del problema anterior pasa por implementar una cola LIFO (es decir Last Input-First output) en la que iremos introduciendo los sonidos que queramos para que vayan sonando por orden de entrada.
La gestión de la cola LIFO la realizaremos sobre un array de 10 elementos:
#define MAXSONIDO 10 unsigned char * Buffer_de_Sonidos[MAXSONIDO]; unsigned int Buffer_de_TSonidos[MAXSONIDO];
Utilizando las siguientes tres funciones:
// Gestión de la cola LIFO de sonidos
int cola = 0, cabeza = 0;
bool InsertarSonido(void* pointer, unsigned int size){
int temp = cola;
cola++;
if (cola==MAXSONIDO) cola=0;
if (cola == cabeza){
cola = temp;
return false;
} else {
Buffer_de_Sonidos[cola]=pointer;
Buffer_de_TSonidos[cola]=size;
return true;
}
}
bool ColaSonidosVacia(void){
return cola==cabeza;
}
void* SacarSonido(unsigned int * size){
if (cola == cabeza) {
return false;
} else {
cabeza++;
if (cabeza==MAXSONIDO) cabeza=0;
*size = Buffer_de_TSonidos[cabeza];
return Buffer_de_Sonidos[cabeza];
}
}
Equipados ya con nuestras funciones de gestión de colas comenzamos ya de lleno en el código del main. Para la inicialización de vídeo he utilizado exactamente lo mismo que en tutorial anterior agrupando toda esta tarea en la función setup_video();.
Al igual que en tutorial anterior, seguidamente inicializamos las librerías de sonido, cargamos las texturas e inicializamos los mandos.
cargar_texturas(); ASND_Init(); ASND_Pause(0); // Esta función inicializa los PADs conectados WPAD_Init(); // Asigna la resolucion que nos devuelve el IR WPAD_SetVRes(WPAD_CHAN_0, 640, 480); // ajusta el modo de operación de los PADS activando acelerometros y el IR WPAD_SetDataFormat(WPAD_CHAN_0, WPAD_FMT_BTNS_ACC_IR); cargar_texturas(); ASND_Init(); ASND_Pause(0); // Esta función inicializa los PADs conectados WPAD_Init(); // Asigna la resolucion que nos devuelve el IR WPAD_SetVRes(WPAD_CHAN_0, 640, 480); // ajusta el modo de operación de los PADS activando acelerometros y el IR WPAD_SetDataFormat(WPAD_CHAN_0, WPAD_FMT_BTNS_ACC_IR);
Una vez hemos hecho todo esto pediremos al usuario que encienda la Balance board, para lo cual insertaremos el sonido correspondiente en la cola de sonidos.
InsertarSonido(&enciendeme, enciendeme_size);
Ya dentro del bucle principal nos encontramos con la llamada a la función Sonidos() que se encarga de gestionar los sonidos que hay en la cola de sonidos. Dentro de dicha función podemos ver lo siguiente:
unsigned char * pointer=0; unsigned int size; if (ASND_StatusVoice(1)==SND_WAITING||ASND_StatusVoice(1)==SND_UNUSED) { pointer = SacarSonido(&size); if (pointer) { cont++; ASND_SetVoice( 1, VOICE_MONO_8BIT, 8000, 0, pointer, size, 255, 255, NULL); } }
Como se puede ver la función comprueba si no está sonando otro sonido en el canal 1 y sólo en ese caso recupera un nuevo elemento de la cola de sonidos y lo hace sonar con la función ASND_SetVoice.
El formato de la función ASND_SetVoice es el siguiente:
s32 ASND_SetVoice (s32 voice, s32 format, s32 pitch, s32 delay, void * snd, s32 size_snd, s32 volume_l, s32 volume_r, ASNDVoiceCallback callback)
/************* Limpia la memoria *************/ // Asigna el viewport GX_SetViewport(0,0,rmode->fbWidth,rmode->efbHeight,0,1); // limpiar la cache de vertices GX_InvVtxCache(); // limpiar la memoria de texturas GX_InvalidateTexAll(); // cargamos textura correcta GX_LoadTexObj(&texObj, GX_TEXMAP0); // limpia todos los atributos de vertice GX_ClearVtxDesc(); // Vuelve a asinar los atributos de vertice GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); // Comienza cargando la matriz identidad en GXmodeView2D guMtxIdentity(GXmodelView2D); // Movemos el modelo 5.0f unidades hacia atras sobre el eje Z guMtxTransApply (GXmodelView2D, GXmodelView2D, 0.0F, 0.0F, -5.0F); GX_LoadPosMtxImm(GXmodelView2D,GX_PNMTX0);
WPAD_IR(pad, &ir);
dibujar_fondo(); dibujar_Boton();
void dibujar_fondo(void){ GX_Begin(GX_QUADS, GX_VTXFMT0, 4); GX_Position2f32(0, 0); GX_TexCoord2f32(0.0,0.0); GX_Position2f32(639, 0); GX_TexCoord2f32(1.0,0.0); GX_Position2f32(639,479); GX_TexCoord2f32(1.0,0.79); GX_Position2f32(0,479); GX_TexCoord2f32(0.0,0.79); GX_End(); }
// Esto lee el estado de los mandos a cada ciclo del bucle WPAD_ScanPads(); int ret = -1; for (i=0;i<WPAD_MAX_WIIMOTES;i++) //always check that's its there { u32 devtype; ret = WPAD_Probe(i,&devtype); if ((ret==WPAD_ERR_NONE) && (devtype==WPAD_EXP_WIIBOARD)) { wbb=i; check=true; break; } }
if (check){ if (!agradecido) { if (ASND_TestVoiceBufferReady(1)) { // agradecer el encendido de la tabla InsertarSonido(&gracias, gracias_size); // pedir al usuario que se suba al la tabla InsertarSonido(&PSM, PSM_size); agradecido = true; } } // Lectura de los datos de la tabla y cálculo del peso WPAD_Expansion(wbb, &exp); x=exp.wb.x; y=exp.wb.y; weight=exp.wb.tl+exp.wb.tr+exp.wb.bl+exp.wb.br; // Peso en Kg //desglose del peso en centenas, decenas y unidades centena = weight/100; decena = fmod(weight,100)/10; unidades = fmod(weight,10); // Mostrarlos valores desglosados en cada uno de los dígitos dibujar_centena(centena); dibujar_decena(decena); dibujar_unidades(unidades); } else { x=0; y=0; weight = 0; agradecido = false;} if (check){ if (!agradecido) { if (ASND_TestVoiceBufferReady(1)) { // agradecer el encendido de la tabla InsertarSonido(&gracias, gracias_size); // pedir al usuario que se suba al la tabla InsertarSonido(&PSM, PSM_size); agradecido = true; } } // Lectura de los datos de la tabla y cálculo del peso WPAD_Expansion(wbb, &exp); x=exp.wb.x; y=exp.wb.y; weight=exp.wb.tl+exp.wb.tr+exp.wb.bl+exp.wb.br; // Peso en Kg //desglose del peso en centenas, decenas y unidades centena = weight/100; decena = fmod(weight,100)/10; unidades = fmod(weight,10); // Mostrarlos valores desglosados en cada uno de los dígitos dibujar_centena(centena); dibujar_decena(decena); dibujar_unidades(unidades); } else { x=0; y=0; weight = 0; agradecido = false;}
if (ASND_TestVoiceBufferReady(1)) { // agradecer el encendido de la tabla InsertarSonido(&gracias, gracias_size); // pedir al usuario que se suba al la tabla InsertarSonido(&PSM, PSM_size); agradecido = true; }
// Lectura de los datos de la tabla y cálculo del peso WPAD_Expansion(wbb, &exp); x=exp.wb.x; y=exp.wb.y; weight=exp.wb.tl+exp.wb.tr+exp.wb.bl+exp.wb.br; // Peso en Kg
dibujar_centena(centena); dibujar_decena(decena); dibujar_unidades(unidades);
void dibujar_digito(int x, int y, int n){ float tx = n*0.092+0.070; float ty = 0.81; float h = 0.075; float w = 0.072; float dw=43; float dh=45; GX_Begin(GX_QUADS, GX_VTXFMT0, 4); GX_Position2f32(x, y); GX_TexCoord2f32(tx,ty); GX_Position2f32(x+dw, y); GX_TexCoord2f32(tx+w,ty); GX_Position2f32(x+dw,y+dh); GX_TexCoord2f32(tx+w,ty+h); GX_Position2f32(x,y+dh); GX_TexCoord2f32(tx,ty+h); GX_End(); } void dibujar_centena(int n){ dibujar_digito(248, 106, n); } void dibujar_decena(int n){ dibujar_digito(305, 106, n); } void dibujar_unidades(int n){ dibujar_digito(362, 106, n); }
u32 pressed = WPAD_ButtonsDown(pad);
dibujar_CG(x, y);
dibujar_mano(ir.x, ir.y, ir.angle);
void dibujar_mano(int x, int y, float angle){ Mtx model; guVector Zaxis = {0,0,1}; guMtxIdentity(model); guMtxRotAxisDeg(model, &Zaxis, angle); guMtxTransApply(model, model, x, y, 0); // load the modelview matrix into matrix memory GX_LoadPosMtxImm(model, GX_PNMTX0); GX_Begin(GX_QUADS, GX_VTXFMT0, 4); GX_Position2f32(-20, -30); GX_TexCoord2f32(0.0,0.807); GX_Position2f32(+20, -30); GX_TexCoord2f32(0.055,0.807); GX_Position2f32(+20,+30); GX_TexCoord2f32(0.055,0.895); GX_Position2f32(-20,+30); GX_TexCoord2f32(0.0,0.895); GX_End(); }
Si pulsamos el botón A y el puntero está dentro de los límites del botón { Si la centena es 1 { Si es el número 100 leemos “cien” En caso contrario leemos ciento } Si la centena es 2 leemos “doscientos” Si la decena es 1{ Si las unidades están entre 1 y 5 leer “once”, “doce”..... o “quince” En caso contrario leer “diez” } Si la decena es 2{ Si es el número 20 leer “veinte” En caso contrario leer “veinti” } Si la decena está entre 3 y 9 leer “treinta”, “cuarenta”…..o “noventa” Leer “y” salvo en los siguientes casos: El número es menor de 15 veinte que se lee “veinti” Es múltiplo de 10 Si el número no está entre 10 y 15 Si el número es exactamente 0 entonces leer “cero” Si las unidades están entre 1 y 9 Leer las unidades (“uno”, “dos”, “tres”…… “nueve”) Leemos “Kilogramos”
if ((pressed & WPAD_BUTTON_A) && (ir.x >= 275) && (ir.x <= 380) && (ir.y >= 450) && (ir.y <= 479)) { switch (centena) { case 1: if ((decena==0)&&(unidades==0)) { //si es el 100 leemos “cien” InsertarSonido(&cien, cien_size); } else { InsertarSonido(&ciento, ciento_size); //en otro caso “ciento” } break; case 2: InsertarSonido(&doscientos, doscientos_size); break; } switch (decena) { case 1: switch (unidades){ case 1: InsertarSonido(&once, once_size); break; case 2: InsertarSonido(&doce, doce_size); break; case 3: InsertarSonido(&trece, trece_size); break; case 4: InsertarSonido(&catorce, catorce_size); break; case 5: InsertarSonido(&quince, quince_size); break; default: InsertarSonido(&diez, diez_size); break; } break; case 2: if (unidades==0) InsertarSonido(&veinte, veinte_size); else InsertarSonido(&veinti, veinti_size); break; case 3: InsertarSonido(&treinta, treinta_size); break; case 4: InsertarSonido(&cuarenta, cuarenta_size); break; case 5: InsertarSonido(&cincuenta, cincuenta_size); break; case 6: InsertarSonido(&sesenta, sesenta_size); break; case 7: InsertarSonido(&setenta, setenta_size); break; case 8: InsertarSonido(&ochenta, ochenta_size); break; case 9: InsertarSonido(&noventa, noventa_size); break; } if ((decena != 2) && (unidades != 0) && (decena != 0) && (!((decena==1)&&(unidades<=5)))) InsertarSonido(&sonidoy, sonidoy_size); if ((decena != 1) || (unidades > 5)) { switch (unidades) { case 0: if ((decena==0)&&(centena==0)) InsertarSonido(&cero, cero_size); break; case 1: InsertarSonido(&uno, uno_size); break; case 2: InsertarSonido(&dos, dos_size); break; case 3: InsertarSonido(&tres, tres_size); break; case 4: InsertarSonido(&cuatro, cuatro_size); break; case 5: InsertarSonido(&cinco, cinco_size); break; case 6: InsertarSonido(&seis, seis_size); break; case 7: InsertarSonido(&siete, siete_size); break; case 8: InsertarSonido(&ocho, ocho_size); break; case 9: InsertarSonido(&nueve, nueve_size); break; } } InsertarSonido(&Kilogramos, Kilogramos_size); }
Comentarios
Ya quiero ver un app con tu nombre.
Tengo que verlo. Muy buenos tutoriales.
Paz!!
Estoy en ello
Estoy en ello Rayosbute....
Primero espero publicar una más sencilla para ir soltando la mano, y más adelante ya tengo pensado algo con modelado en 3D, pero de momento esa esperará un poco.
Por cierto, para esa segunda aplicación me vendría de maravilla alguien que tuviera buena mano con el 3DStudio....interesados enviadme un MP.
Curso aplicado de GRRLIB - Parte 1 - Parte 2 - Parte 3 - Parte 4 - Parte 5 - Parte 6 - Parte 7 - Parte 8 - Parte 9 - Parte 10 - Parte 11
Profundizando en los mandos de la Wii - Parte 1 - Parte 2 - Parte 3 - Parte 4 (Balanceboard) - Parte 5 (Miis)
Homebrew - WiiTriis - LifemiiWii
Creo que
Creo que tenemos la misma idea, hacer modelos 3d de objetos y a partir de ahi generar "sprites" usables para un juego, manejo 3d max y estoy casi igual que tu, buscando gente que sepa de lo mismo para poder tirarme al agua con un juego de wii, creo que tu lo lograras antes que yo xD, saludos
Cultura de un Videojugador: Cheats
Otras entradas de bitácora
Te propongo que colaboremos
Te propongo que colaboremos en algún programa.
De momento estoy programando una aplicación en 3D que creo que puedo tener lista en una o dos semanas.
No creo que el tema sea el colmo de la popularidad pero yo estoy disfrutando y sobre todo aprendiendo para futuras aplicaciones.
Para los que tienen algunos años a sus espaldas, como yo, y les gustan los temas científicos, igual recuerdan una sección de la revista Scientific American que llevaba A.K. Dewdney y que se llamaba Computer Games y que proponía un tema de programación cada mes.
En esta sección se trataban temas de programación recreativa basada en conceptos científicos y de simulación.
En uno de los números de la revista, propuso la programación de una versión en 3D de un programa de simulación de automatas celulares ideado por John Conway y llamado "The Game of Life" http://en.wikipedia.org/wiki/Conway's_Game_of_Life
Mi programa es una implementación para Wii de ese programa en 3D, con su editor de mundos y de artefactos. Además se utiliza los Mii como forma de seleccionar tu configuración.
Con este programa estoy tocando un poco de todo, manejo de los mandos, introducción de textos por pantalla, programación en 3D, acceso a ficheros en la SD y en la NAND, texturas, botones, menús.........
Cuando acabe con este programa pretendo hacer algo más comercial, pero me vendría bien algo de colaboración, por lo que si te animas, estoy dispuesto a formar equipo.
Dime algo.
Curso aplicado de GRRLIB - Parte 1 - Parte 2 - Parte 3 - Parte 4 - Parte 5 - Parte 6 - Parte 7 - Parte 8 - Parte 9 - Parte 10 - Parte 11
Profundizando en los mandos de la Wii - Parte 1 - Parte 2 - Parte 3 - Parte 4 (Balanceboard) - Parte 5 (Miis)
Homebrew - WiiTriis - LifemiiWii
yo me apunto
yo me apunto a trabajar contigo, pero definitivamente no puede ser ahora, tendria que ser de aqui a unos 2~3 meses si todo va como lo planeo ya que afortunadamente tengo un trabajo grande que cumplir, ademas estoy metido en varios proyectos que van desde musica hasta organización de eventos (pensamos hacer un "tetris con humanos" con musica en vivo y eso en una convencion en mi pais, pero de momento todo esta de cabeza) y si te digo que si ahora te quedaria mal y es algo que no quiero, por otro lado, lo que comentas es realmente impresionante e interesante, me encantan los temas de inteligencia artificial (y a la vez los odio porque pueden ser muy complicados), hablando con un amigo pensabamos crear un juego pero mas dinamico, te mencionaba lo del 3D porque el juego que pensamos hacer es de naves al mero estilo de los años 90, pero los modelos de las naves tendrian bases en modelos 3D y a partir de ahi se sacan los sprites colocando los modelos en distintas posiciones, hasta cierto punto es mas facil de la forma que te estoy diciendo, y la programación es similar a un juego Sidescroll, volviendo al tema, me gustaria colaborar contigo pero te repito, en este momento no puedo ya que como dicen, quien mucho abarca poco aprieta y si me pongo en otro proyecto de este tamaño todo me va a colapsar y quedare mal con todo mundo y es algo que definitivamente no quiero, un saludo
Cultura de un Videojugador: Cheats
Otras entradas de bitácora
Pues cuando tengas tiempo,
Pues cuando tengas tiempo, aquí estoy. No tienes más que decírmelo y buscamos un tema de programación.
Suerte con el trabajo que llevas entre manos.
Curso aplicado de GRRLIB - Parte 1 - Parte 2 - Parte 3 - Parte 4 - Parte 5 - Parte 6 - Parte 7 - Parte 8 - Parte 9 - Parte 10 - Parte 11
Profundizando en los mandos de la Wii - Parte 1 - Parte 2 - Parte 3 - Parte 4 (Balanceboard) - Parte 5 (Miis)
Homebrew - WiiTriis - LifemiiWii
wm+ y Blender 3D
exelentes tutos
tienes pensado tratar el uso del wm+?
seria interesante poder usar esta tecnologia.
y tambien; yo sugiero el uso de Blender en lugar del 3Dstudio.
digo, si ya usaste el Audacity, por que no recomendar el Blender.
He sugerido 3DStudio porque
He sugerido 3DStudio porque es el formato que conozco. He encontrado por ahí como interpretar los archivos 3DS para convertirlos en vertices en un array.
De todas formas lo único que necesito es un archivo final .3DS o la forma de leer el formato de Blender.
Curso aplicado de GRRLIB - Parte 1 - Parte 2 - Parte 3 - Parte 4 - Parte 5 - Parte 6 - Parte 7 - Parte 8 - Parte 9 - Parte 10 - Parte 11
Profundizando en los mandos de la Wii - Parte 1 - Parte 2 - Parte 3 - Parte 4 (Balanceboard) - Parte 5 (Miis)
Homebrew - WiiTriis - LifemiiWii
Excelente Wilco, saludos!
Excelente Wilco, saludos!
Muchas gracias Javi!!
Muchas gracias Javi!!