Moonseeds: didáctica espacial en la NintendoDS
Full text
DIDÁCTICA ESPACIAL EN LA PROYECTO FINAL DE CARRERA DIRECTOR: Manuel Agustí Melchor ALUMNO: Héctor Cuñat Núñez VALENCIA, JUNIO 2011
ÍNDICE INTRODUCCIÓN ................................................................................................. 7 HARDWARE NDS .............................................................................................. 13 OTROS MODELOS ................................................................................................. 15 POTENCIA GRÁFICA .............................................................................................. 15 ENTORNO DE DESARROLLO .............................................................................. 17 LIBRERÍAS UTILIZADAS .......................................................................................... 17 MAKEFILE UTILIZADO ........................................................................................... 19 FLASHCARTS Y DLDI.......................................................................................... 23 DISEÑO GAMEPLAY .......................................................................................... 27 DISEÑO ARTÍSTICO ........................................................................................... 31 MODELADO Y TEXTURAS .................................................................................. 37 CREACIÓN DE LOS MODELOS TRIDIMENSIONALES .............................................. 37 BOX MODELING Y QUADS .................................................................................... 38 TEXTURAS ............................................................................................................. 40 INTEGRACIÓN EN LA APLICACIÓN ........................................................................ 43 ANIMACIÓN DE LOS MODELOS ............................................................................ 46 CARGADOR DE *.OBJ's ..................................................................................... 49 FORMATO OBJ ...................................................................................................... 49 CARGADOR DE *.OBJ's .......................................................................................... 51 SISTEMA DE RESPUESTA ................................................................................... 57
OTRAS FUNCIONES UTILIZADAS ........................................................................ 65 PALIB ..................................................................................................................... 65 LIBFAT ................................................................................................................... 68 ASLIB ..................................................................................................................... 68 CONCLUSIONES Y POSIBLES AMPLIACIONES...................................................... 71 Nintendo3DS ........................................................................................................ 73 BIBLIOGRAFÍA .................................................................................................. 75 ANEXO I ........................................................................................................... 79 ANEXO II ........................................................................................................ 107 ÍNDICE ANÁLITICO .......................................................................................... 113 ÍNDICE DE FIGURAS ........................................................................................ 115
5
6
7 INTRODUCCIÓN El presente proyecto surge como una continuación del trabajo realizado en la asignatura Integración de Medios digitales, de la titulación de Ingeniero Técnico en Informática de Sistemas, de la Universidad Politécnica de Valencia. Dicho trabajo (el cual se recoge como anexo en la presente memoria) consistió en la implementación de una aplicación educativa para NintendoDS donde los alumnos de Educación Secundaria puedan educar la visión espacial mientras juegan. Gracias a la base técnica adquirida durante el trabajo de la asignatura, a la ayuda del director del presente proyecto y a la colaboración de los alumnos del centro en el que trabajo como profesor (figura 1), pudieron alcanzarse objetivos aún más ambiciosos. Fig. 1: Alumnado del CEIP Eliseo Vidal, el cual ha sido consultado en repetidas ocasiones durante la elaboración del presente proyecto.
14 Dicho hardware 3D está diseñado para dibujar una sola pantalla por ciclo de reloj, por lo que cuando se dibujan imágenes 3D diferentes en ambas pantallas, la velocidad disminuye notablemente. La memoria de vídeo (VRAM) es de 656 KB y está estructurada según el mapa de memoria mostrado en la figura 3: Donde los bancos de memoria A,B,C y D pueden utilizarse para almacenar texturas (disponiendo así de 512KB para ello, dando lugar a un tamaño máximo de textura de 1024x1024 píxeles). Tiene compatibilidad con WiFi IEEE 802.11b. La unidad también soporta un protocolo especial inalámbrico creado por Nintendo utilizado en el programa de chat PictoChat). La conexión WiFi se usa para acceder a Internet o para su uso en el modo multijugador de algunos juegos. Fig. 3: Mapa de memoria de la VRAM (imagen obtenida de http://dev-scene.com).
15 OTROS MODELOS NintendoDS Lite Consola portátil fabricada por Nintendo en 2006 y desarrollada para suceder a la NintendoDS. Las únicas novedades fueron la estética, mucho más estilizada y pulida, y la posibilidad de elegir entre cuatro niveles de brillo. NintendoDSi Nuevo modelo con un diseño muy similar al de la DS Lite, pero con pantallas ligeramente más grandes y con dos cámaras interactivas de 0.3 megapíxeles que pueden ser utilizadas para tomar fotografías. Posee una nueva interfaz al estilo Wii de Nintendo, ranura de tarjeta SDHC, navegador de Internet, conexión a la Tienda NintendoDSi y posibilidad de subir fotos a Facebook directamente desde la consola. NintendoDSiXL Modelo idéntico al anterior salvo por un tamaño de pantalla notablemente mayor ( 4,2'' frente a las 3,25" de la DSi y las 3" de la DSLite). POTENCIA GRÁFICA Para tener una idea concreta de la potencia gráfica 3D de la NintendoDS, se crearon dos ejecutables a partir del código del ejemplo 6 (figura 4) de la famosa serie de tutoriales sobre OpenGL de NeHe (http://nehe.gamedev.net). Ambos emplean las mismas instrucciones de OpenGL y muestran la misma escena por pantalla, mostrando además el número de frames por segundo. Sin embargo, el primero fue escrito para ejecutarse en una en una NintendoDS y el segundo para ejecutarse en diferentes PCs.
16 Así pues, comparando el número de frames por segundo empleado por cada ejecutable para representar las escena podemos hacernos una idea de la potencia relativa de cada una de las plataformas en que se ha ejecutado, tal como se muestra en la figura 5: A pesar de que a simple vista queda patente la poca potencia que presenta una NintendoDS, ésta es aún menor en realidad, puesto que el portátil y el ordenador de sobremesa representaron la escena a una resolución de 1280x1024 píxeles mientras que la NintendoDS únicamente a una resolución de 255x192 píxeles. Así pues, dada la poca potencia del dispositivo elegido, resulta de extrema importancia la optimización en todo aquello relativo a la programación gráfica 3D, como se detallará en los apartados Modelado y Texturas y Cargador de *.obj's de la presente memoria. Fig. 4: Al ejecutar el ejemplo 6 de NeHe, se muestran por pantalla una pirámide y un cubo girando sobre sí mismos. Fig. 5: Resultados obtenidos en diferentes tipos de equipos.
17 ENTORNO DE DESARROLLO Tal como se especifica en el capítulo de introducción, la presente aplicación se programó en un ordenador personal bajo el sistema operativo Windows 7. Para la escritura y edición de código fuente, en lenguaje C, se utilizó el programa Notepad++ (figura 6), compilando dicho código mediante el compilador DevkitARM, incluido en la cadena de herramientas DevKitPro. Las distintos ejecutables fueron testados en el emulador NO$GBA 2.6 y ejecutados directamente sobre una NintendoDS Lite mediante el uso de los flashcarts SupercardSD y M3iZero. LIBRERÍAS UTILIZADAS LibNDS (v1.4.10) LibNDS es una librería creada por Michael Noland (joat) y Jason Rogers (dovoto) y actualmente mantenida por Dave Murphy (WinterMute). Pretende ser una alternativa open source al SDK comercial de Nintendo para la consola NintendoDS. Libnds da soporte a prácticamente todas las funcionalidades de la DS, incluyendo pantalla táctil, micrófono, hardware 3D, hardware 2D y WiFi. Fig. 6: Notepad++ reconoce y colorea la sintaxis del código escrito en lenguaje C.
18 Es importante destacar que éstas son librerías de bajo nivel, incluidas en DevKitPro y que su API (http://libnds.devkitpro.org) contiene las instrucciones de OpenGL que permitirán la programación gráfica 3D. LibFAT (v1.0.9) Incluidas también dentro de la cadena de herramientas DevKitPro, estas librerías permiten el acceso al sistema de archivos del flashcart utilizado, permitiendo cargar ficheros de forma externa al ejecutable. Fueron creadas, y están actualmente mantenidas, por Chishm (http://chishm.drunkencoders.com). ASLib (v1.0) Librerías creadas por Noda (http://nodadev.wordpress.com) y utilizadas en la reproducción de música de fondo en formato mp3 y de efectos sonoros en formato raw. Estas librerías fueron utilizadas en lugar de las MaxMod, al contrario de lo que inicialmente se planeó, debido a su sencillez, a la funcionalidad de reproducir archivos de audio en formato mp3 y por no requerir la elaboración previa de una biblioteca de sonidos. PAlib (beta 100707) Librerías creadas por Mollusk y actualmente abandonadas. Al ser unas librerías construidas sobre las libNDs, proveen funciones de más alto nivel que facilitan considerablemente la programación para NintendoDS. Gracias a la inclusión de estas librerías (no se había hecho uso de ellas en el proyecto realizado en la asignatura IMD) se ha podido añadir a la aplicación funcionalidades tan interesantes como acceso al reloj del sistema, teclado táctil,... de una forma casi inmediata.
19 MAKEFILE UTILIZADO Un makefile es un archivo de texto utilizado en la gestión de compilación de programas. En él se recogen las dependencias entre las diferentes partes de un proyecto. Todos los makefiles están ordenados en forma de reglas, especificando qué ha de hacer el compilador para obtener un módulo en concreto. Sin embargo, como se detalla en el anexo de la presente memoria (en el punto Integración de las distintas funcionalidades en una única aplicación), una de las dificultades que más tiempo consumió fue la elaboración de un makefile que integrase las dependencias requeridas por las distintas funcionalidades de la aplicación. En concreto, podemos leer: "La primera gran dificultad radica en que el Makefile que nos permite cargar los modelos en 3D no está preparado para trabajar con GRIT, y el Makefile del proyecto de ejemplo que permite cargar fondos, no permite la manipulación de figuras tridimensionales". Afortunadamente, la instalación de las librerías PAlib soluciona este problema de forma inmediata, pues proporciona un makefile "universal" donde intenta recoger el conjunto de dependencias y reglas requeridas por los distintos tipos posibles de fichero. Para ello, dichos ficheros deben encontrarse en la carpeta adecuada dentro del directorio del proyecto, tal como se muestra en la figura 7: Fig. 7: Contenido de una carpeta de proyecto. Incluiremos los ficheros de código fuente en la carpeta source, los fondos y los sprites en la carpeta gfx (figura 8), los archivos de sonido en la carpeta audio y los modelos tridimensionales y sus correspondientes texturas en la carpeta data. Con build.bat generaremos el ejecutable, creado por el compilador a partir de las dependencias especificadas en el makefile.
20 Abriendo dicho makefile con un editor de texto, podemos acceder e incluso editar la siguiente información de interés (figura 9): #Especificamos el core a cargar en el procesador secundario, en este caso la opción por #defecto: arm7_mp3.bin, la cual nos proporcionará funcionalidades de reproducción de #archivos de sonido en *.mp3. ... ifeq ($(strip $(ARM7_SELECTED)), ARM7_MP3) ARM7BIN := $(PAPATH)/lib/arm7_mp3.bin ARM7_IS_OK := YES endif ... #Seleccionamos ahora aquellas librerías que queramos incluir en nuestro proyecto. ... ifeq ($(strip $(ARM7_SELECTED)), ARM7_MP3) LIBS := -lfilesystem -lfat -lnds9 endif ... Fig. 8: Dentro de la carpeta gfx podemos encontrar la aplicación PAGfx, la cual nos permitirá transformar los sprites, los fondos y las texturas a un formato compatible con la NintendoDS.
21 Vemos cómo para incluir una nueva librería externa a PAlib, basta con añadir su nombre, precedido de un guión, a la lista de librerías. Es necesario explicar que no se hace referencia a la librería de sonido ASlib por estar incluida dentro de la versión utilizada de PAlib. #Indicamos dónde se encuentran los archivos de código fuente... ... CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) ... # ...y los distintos recursos incluidos en la aplicación (fondos, música, modelos,...). ... BINFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.bin))) MP3FILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.mp3))) ... Cabe señalar que no se hace referencia directa a archivos de imagen ni a modelos tridimensionales y texturas porque éstos han sido convertidos previamente a formato *.bin (mediante el programa PAGfx o los programas NDS_Mesh_Converter y bmp2bin) tal como se verá más adelante en el punto Modelado y Texturas de la presente memoria. # Por último especificamos las reglas para la construcción de... # ...el ejecutable: #------------------------------------------------------------------ %.nds: %.bin #------------------------------------------------------------------ @ndstool -c $@ -9 $(TARGET).bin -7 $(ARM7BIN) -b $(ICON) "$(TEXT1);$(TEXT2);$(TEXT3)" $(FILESYSTEM) > /dev/null @echo @echo Built: $(notdir $@) @echo
22 # ...el código fuente: #------------------------------------------------------------------ %.o: %.cpp #------------------------------------------------------------------ @echo $(notdir $<) @$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ #------------------------------------------------------------------ %.o: %.c #------------------------------------------------------------------ @echo $(notdir $<) @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) -c $< -o $@ # ...y los distintos recursos... #------------------------------------------------------------------ %.o: %.bin #------------------------------------------------------------------ @echo $(notdir $<) @$(bin2o) #------------------------------------------------------------------ %.o: %.mp3 #------------------------------------------------------------------ @echo $(notdir $<) @$(bin2o) # ...los cuales hacen uso de la macro bin2o: define bin2o cp $< $* bin2s $* | $(AS) -o $@ rm $* echo "extern const u8" $*"[];" > $*.h echo "extern const u32" $*_size";" >> $*.h endef Fig. 9: Fragmentos del makefile incluido en PALib.
23 FLASHCARTS Y DLDI Los flashcarts son dispositivos utilizados para ejecutar programas caseros (homebrew) en la NintendoDS, ya que ésta no se vende con ningún medio regrabable de almacenamiento. Por tanto será necesario el uso de uno de estos dispositivos para poder ejecutar la aplicación programada directamente en una NintendoDS. Cabe remarcar la extrema importancia de conseguir ejecutar la aplicación desarrollada directamente en una NintendoDS: Además de que el emulador no emula el hardware de la videoconsola de forma exacta, no podrán utilizarse aquellas funciones que consulten datos internos de la consola, como puede ser el reloj del sistema. Además, obviamente, tampoco podremos acceder al sistema de archivos del flashcart para cargar elementos externos al ejecutable. Básicamente hay dos tipos de flashcarts (figura 8): los más antiguos, que utilizan la ranura para los juegos de GameBoyAdvance (SLOT-2) y que necesitan de algún dispositivo de arranque en el SLOT-1 (la ranura para los juegos de NintendoDS); y las más modernas, que utilizan directamente el SLOT-1. Fig. 10: Las dos flashcarts utilizadas a lo largo del presente proyecto: SupercardSD, de tipo SLOT-2 y M3iZero, de tipo SLOT-1 (Imágenes obtenidas de http://images.discoazul.com/ y http://www.dsiconsolas.com.
30
31 DISEÑO ARTÍSTICO Dada la iniciativa didáctica de la aplicación, se buscó una estética sencilla que permitiese al alumno concentrarse en la solución técnica de la pregunta planteada y que no desvíe su atención hacia otros aspectos menos importantes. Para poder dirigir dicha atención, se pretendió resaltar con un determinado color los elementos de interés, representando el resto con colores de una misma gama muy distinta a la del color elegido, tal como se muestra en la figura 14: Por otra parte, se escogió como música de fondo el tema Spiegel im Spiegel, de Arvo Part, que permitía ser reproducida cíclicamente a partir de una pista de audio relativamente corta (con el consiguiente ahorro de memoria) y que resultaba especialmente poética y relajante. Por último, cabe decir que el alumnado votó y opinó acerca de cada uno de los bocetos e imágenes realizados (figuras 15 y 16), cada uno de los cuales representaba una posible estética a emplear en la aplicación. Es interesante mencionar además que la gran mayoría opinó que la estética empleada en el proyecto de la asignatura Integración de Medios Digitales resultaba demasiado infantil. Fig. 14: Técnica similar a la descrita utilizada por Frank Miller en su novela gráfica Sin City (Imagen obtenida de http://www.mtv.com/movies).
32 Fig. 15: Bocetos que lograron una mayor aceptación entre el alumnado.
33 Fig. 16: Dibujos coloreados en Photoshop, a partir de los bocetos realizados, para a su uso como fondos en la aplicación
34
35
36
37 MODELADO Y TEXTURAS CREACIÓN DE LOS MODELOS TRIDIMENSIONALES Una vez diseñados los elementos del juego, es hora de crearlos haciendo uso de un paquete de modelado tridimensional, como Autodesk 3DSMAX en el caso del presente proyecto. En primer lugar, conviene tener en todo momento una referencia del diseño elaborado, para asegurarnos que el modelo creado se ajusta al mismo. Para ello, resulta conveniente modelar primero dos planos verticales y perpendiculares entre sí a los que se les aplica como textura los diseños realizados (por ejemplo el protagonista de frente y de perfil, como se muestra en la figura 17). Así pues, con dichas referencias como plantilla, se modelaron cada uno de los elementos tridimensionales de la aplicación, utilizando para ello la técnica conocida como box modeling, detallada en el siguiente punto. Fig. 17: Creación de las referencias artísticas en el paquete de modelado 3D.
38 BOX MODELING Y QUADS La técnica de box modeling consiste en el modelado de figuras relativamente complejas. Se parte de primitivas gráficas sencillas a cuyas caras se les aplican sucesivas subdivisiones, extrusiones y diversas transformaciones espaciales, tal como se muestra en la figura 18: Este método, además de ser relativamente sencillo, resulta notablemente más rápido que la manipulación individual de cada uno de los vértices. El elemento fundamental en la técnica de box modeling son las caras de cuatro lados, comúnmente llamadas quads, las cuales permiten resultados predecibles y consistentes, ya que pueden subdividirse en 2 o 4 triángulos (trazando una o dos diagonales) que poseen aproximadamente la misma dirección de la normal (recordemos que la gran mayoría de los motores de videojuegos interpreta las geometrías como tiras de triángulos). Así pues, intentaremos que nuestros modelos estén siempre formados por quads en la medida de lo posible, siendo esto estrictamente obligatorio en el caso de las figuras problema, pues éstas se representarán en pantalla mediante el código descrito en la figura 29 (punto Cargador de *.obj's) cuya funcionalidad se limita a la representación de figuras integradas por quads. Fig. 18: Proceso de modelado del telescopio mediante la técnica de box modeling.
39 Adicionalmente, en el punto: Importación, manipulación y texturización de figuras 3D (contenido en el Anexo I de la presente memoria) se muestra el código necesario para la manipulación y texturización de un quad en pantalla y se plantea cómo crear figuras más complejas a partir del mismo, tales como el laberinto tridimensional mostrado en la figura 19: Por último, tal como se refleja en el apartado de hardware de la presente memoria, la NDS resulta un dispositivo relativamente poco potente a la hora de procesar gráficos tridimensionales. Así pues, se buscó que los modelos creados fuesen sencillos (con un número de polígonos nunca superior a 1000 (figura 20)). Fig. 19: Laberinto similar al del juego Wolfenstein3D (ID software, 1992) formado por una serie de quads texturizados. Fig. 20: Modelos empleados en la aplicación, mostrando su sencilla malla geométrica.
46 ANIMACIÓN DE LOS MODELOS En aquellos elementos animados cuya animación estaba basada únicamente en una transformación de movimiento o de escala, ésta se generó por código, mediante instrucciones de OpenGL, de forma similar a la vista en el punto anterior, tal como se muestra en la figura 27: ... int posX=0, posY=0; while (1){ glPushMatrix(); glTranslate3f32(posX, 0, floattof32(-1)); glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK) ; glBindTexture(0, textureID[0]); glCallList((u32*)modelo00); glEnd(); glPopMatrix(1); glPushMatrix(); glTranslate3f32(0, posY, floattof32(-1)); glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK) ; glBindTexture(1, textureID[1]); glCallList((u32*)modelo01); glEnd(); glPopMatrix(1); glFlush(0); PA_WaitForVBL(); posX++; posY++; } ... Fig. 27: Fragmento de código que mostraría el desplazamiento del modelo00 a lo largo del eje X y del modelo01 a lo largo del eje Y.
47 Sin embargo, cuando la animación de un modelo implicaba además un cambio en la posición relativa de sus vértices (como por ejemplo el ciclo de correr del protagonista, figura 28), se hizo necesario generar dicha animación dentro del paquete de modelado e importarla posteriormente, fotograma a fotograma. Fig. 28: Animación de 20 fotogramas que reproducidos alternativamente en sentidos contrarios (del 1 al 20, del 20 al 1, del 1 al 20, del 20 al 1...) provocan la sensación de carrera del protagonista.
48
49 CARGADOR DE *.OBJ's FORMATO OBJ Recordemos una vez más la importancia de que nuestra aplicación posea la funcionalidad de cargar de forma externa las distintas figuras en las que se basará el test, dotando así a la aplicación de gran versatilidad y de un tiempo de vida virtualmente ilimitado. OBJ es un formato de archivo utilizado para la definición espacial de modelos tridimensionales. En un inicio fue desarrollado por Wavefront Technologies para ser usado en aplicaciones propias, pero debido a ser un formato abierto, fue adoptado también por otras muchas aplicaciones 3D, siendo hoy en día un formato universalmente adoptado. La elección de dicho formato para nuestras figuras problema viene dado por el hecho de que un *.obj es en realidad un archivo de texto que contiene la descripción de una superficie y que permite, por tanto, la lectura y edición desde un simple editor de texto. En la figura 29 vemos el contenido de un archivo *.obj, que contiene la geometría de un cubo creado en 3DSMAX, abierto desde el bloc de notas: # object cubo #Listado de los 8 vértices del cubo v -12.5000 -12.5000 -12.5000 v -12.5000 12.5000 -12.5000 v 12.5000 12.5000 -12.5000 v 12.5000 -12.5000 -12.5000 v -12.5000 -12.5000 12.5000 v 12.5000 -12.5000 12.5000 v 12.5000 12.5000 12.5000 v -12.5000 12.5000 12.5000 # 8 vertices
50 #Listado de las normales de las 6 caras del cubo vn 0.0000 0.0000 -1.0000 vn 0.0000 -0.0000 1.0000 vn 0.0000 -1.0000 -0.0000 vn 1.0000 0.0000 -0.0000 vn 0.0000 1.0000 0.0000 vn -1.0000 0.0000 -0.0000 # 6 vertex normals #Listado de las coordenadas de texturización del cubo vt 1.0000 0.0000 0.0000 vt 1.0000 1.0000 0.0000 vt 0.0000 1.0000 0.0000 vt 0.0000 0.0000 0.0000 # 4 texture coords #Listado con la relación de vértices, normales y coordenadas #de texturización asociadas a # cada cara del cubo g cubo f 1/1/1 2/2/1 3/3/1 4/4/1 f 5/4/2 6/1/2 7/2/2 8/3/2 f 1/4/3 4/1/3 6/2/3 5/3/3 f 4/4/4 3/1/4 7/2/4 6/3/4 f 3/4/5 2/1/5 8/2/5 7/3/5 f 2/4/6 1/1/6 5/2/6 8/3/6 # 6 polygons #Siendo, cada tripleta, (vértice/coord_de_text/normal). #Así, por ejemplo, la última cara (f 2/4/6 1/1/6 5/2/6 0/3/6) está formada por los vértices (2,1,5,0) con las coordenadas de texturización (4,1,2,3) asociadas y la normal de dicha cara es la 6. Fig. 29: Contenido del archivo cubo.obj.
51 CARGADOR DE *.OBJ's Así pues, nuestro cargador de *obj's consistirá básicamente en una aplicación que deberá: 1) Localizar el archivo deseado en el sistema de archivos del flashcart. 2) Abrirlo como un archivo de texto. 3) Leer sus vértices y normales uno a uno, representando en pantalla las distintas caras que dichos vértices forman. En la figura 30 se muestra el código de la función implementada para conseguir dicha funcionalidad: ... //Necesario utilizar las LibFAT para acceder al sistema de archivos #include <fat.h> ... ... //matrices donde almacenaremos los vértices, las coordenadas de texturización y las caras //(límite máximo: objeto de 250 vértices o 100 caras) float v[249][3], vn[249][3]; int faces[99][4][2]; int numfaces; //Nombre de la figura a cargar char figura[20]; ... void leer_figura(){ //Abrimos la figura como si fuera un fichero de texto FILE* f = fopen (figura, "rb"); char oneline[255]; char primera[255]; int i, numverts=0, numnorms=0; int v1, vn1, v2, vn2, v3, vn3, v4, vn4; float xf, yf, zf; numfaces=0;
52 while (!feof(f)){ fgets(oneline,255,f); sscanf(oneline, "%s ", primera); if(strcmp(primera, "v")==0){ sscanf(oneline, "v %f %f %f", &xf, &yf, &zf); v[numverts][0]=xf; v[numverts][1]=yf; v[numverts][2]=zf; numverts++; } if(strcmp(primera, "vn")==0){ sscanf(oneline, "vn %f %f %f", &xf, &yf, &zf); vn[numnorms][0]=xf; vn[numnorms][1]=yf; vn[numnorms][2]=zf; numnorms++; } if(strcmp(primera, "f")==0){ sscanf(oneline, "f %d//%d %d//%d %d//%d %d//%d", &v1, &vn1, &v2, &vn2, &v3, &vn3, &v4, &vn4); faces[numfaces][0][0]=v1; faces[numfaces][0][1]=vn1; faces[numfaces][1][0]=v2; faces[numfaces][1][1]=vn2; faces[numfaces][2][0]=v3; faces[numfaces][2][1]=vn3; faces[numfaces][3][0]=v4; faces[numfaces][3][1]=vn4; numfaces++; } }//del while fclose(f); } Fig. 30: Código de la función encargada de cargar los *.obj externos al ejecutable. Nótese que en ningún momento se ha almacenado la información relativa a la texturización de las figuras. Esto permite un ahorro considerable de memoria además de evitar al usuario la tarea de texturizar las figuras creadas por él (figura 31).
53 Para mostrar por pantalla la figura importada, basta con utilizar la información adquirida por la función leer_figura() para reconstruir el modelo mediante las funciones de OpenGL necesarias, tal como se describe en la figura 32 ... //asociamos la textura predefinida al quad a dibujar en pantalla glBindTexture(0, textureID); //dibujamos las numfaces caras for(i=0; i<numfaces; i++){ //Dibujamos caras de 4 vértices glBegin(GL_QUADS); //La normal a dicha cara glNormal3f(floattov16(vn[faces[i][0][2]-1][0]), floattov16(vn[faces[i][0][2]-1][1]), floattov16(vn[faces[i][0][2]-1][2])); Fig. 31: La aplicación texturiza automáticamente la figura importada, aplicándole a cada cara una textura predefinida y aprovechando así una vez más las ventajas ofrecidas por el uso de tiles.
54 //1er vértice del quad //le asignamos unas coordenadas de texturización GFX_TEX_COORD = (TEXTURE_PACK(0, inttot16(64))); //y especificamos el vértice propiamente dicho glVertex3v16(floattov16(v[faces[i][0][0]-1][0]), floattov16(v[faces[i][0][0]-1][1]), floattov16(v[faces[i][0][0]-1][2])); //2do vértice del quad //le asignamos unas coordenadas de texturización GFX_TEX_COORD = (TEXTURE_PACK(inttot16(64),inttot16(64))); //y especificamos el vértice propiamente dicho glVertex3v16(floattov16(v[faces[i][1][0]-1][0]), floattov16(v[faces[i][1][0]-1][1]), floattov16(v[faces[i][1][0]-1][2])); //3er vértice del quad //le asignamos unas coordenadas de texturización GFX_TEX_COORD = (TEXTURE_PACK(inttot16(64), 0)); //y especificamos el vértice propiamente dicho glVertex3v16(floattov16(v[faces[i][2][0]-1][0]), floattov16(v[faces[i][2][0]-1][1]), floattov16(v[faces[i][2][0]-1][2])); //4to vértice del quad //le asignamos unas coordenadas de texturización GFX_TEX_COORD = (TEXTURE_PACK(0, 0)); //y especificamos el vértice propiamente dicho glVertex3v16(floattov16(v[faces[i][3][0]-1][0]), floattov16(v[faces[i][3][0]-1][1]), floattov16(v[faces[i][3][0]-1][2])); } glEnd(); ... Fig. 32: Código que muestra por pantalla la figura cargada. Como se ha podido ver en el código, y como se explicó en el punto Box Modeling y Quads de la presente memoria, la aplicación únicamente muestra figuras formadas íntegramente por quads, y así ha de tenerlo en cuenta el usuario a la hora de crear y exportar sus propias figuras (ver figura 33). Además, al exportar la figura, también deberá especificar que no es necesario que el *.obj contenga información relativa a las coordenadas de texturización.
55 El usuario deberá tener en cuenta la escala e intentar que las figuras creadas tengan un tamaño similar a la figuras ejemplo que acompañan la aplicación (contenidas en un cubo de aproximadamente 1x1x1 unidades). Del mismo modo, deberá centrar sus figuras en el origen de coordenadas de la aplicación donde las modeló, pues las mismas rotarán alrededor de este punto. Fig. 33: Imagen del exportador de OBJ's incluido en 3DSMAX, donde se especifica que el *.obj creado esté formado únicamente por quads.
62 }else{ p=punto_pulsado(); if(p!=-1){ //Si el stylus está sobre un punto... if(!tocado){ //...y es el primer punto tocado p1=p; tocado=true; x1=PA_GetSpriteX(1,p); y1=PA_GetSpriteY(1,p); } //...si es el segundo punto pulsado, y es distinto al anterior, dibujamos la //arista y el nuevo punto pulsado pasa a ser el último punto pulsado if((PA_GetSpriteX(1,p)!=x1)||PA_GetSpriteY(1,p)!=y1){ PA_Clear8bitBg(1); p2=p; dibuja_arista(p1,p2); p1=p2; x1=PA_GetSpriteX(1,p); y1=PA_GetSpriteY(1,p); } } } ... } //del bucle principal ... } //del main Fig. 40: Código que detecta qué vértices está uniendo el jugador con el stylus. Dicho código hace uso de las siguientes funciones (figura 41), además de las proporcionadas por las librerías PAlib para el tratamiento de sprites: //detectamos el punto pulsado por el stylus y devolvemos -1 cuando no se pulsa ninguno int punto_pulsado(){ int i=0; for(i=0; i<16; i++){ if (PA_SpriteTouchedPix(i)) return i; } return -1; }
63 //metemos un 1 en la posición correspondiente de aristas[], a partir de los 2 puntos unidos void dibuja_arista(int p1, int p2){ //horizontales... if(((p1==0)&&(p2==1))||((p1==1)&&(p2==0))) aristas[0]=1; if(((p1==1)&&(p2==2))||((p1==2)&&(p2==1))) aristas[1]=1; if(((p1==2)&&(p2==3))||((p1==3)&&(p2==2))) aristas[2]=1; if(((p1==4)&&(p2==5))||((p1==5)&&(p2==4))) aristas[3]=1; if(((p1==5)&&(p2==6))||((p1==6)&&(p2==5))) aristas[4]=1; if(((p1==6)&&(p2==7))||((p1==7)&&(p2==6))) aristas[5]=1; if(((p1==8)&&(p2==9))||((p1==9)&&(p2==8))) aristas[6]=1; if(((p1==9)&&(p2==10))||((p1==10)&&(p2==9))) aristas[7]=1; if(((p1==10)&&(p2==11))||((p1==11)&&(p2==10))) aristas[8]=1; if(((p1==12)&&(p2==13))||((p1==13)&&(p2==12))) aristas[9]=1; if(((p1==13)&&(p2==14))||((p1==14)&&(p2==13))) aristas[10]=1; if(((p1==14)&&(p2==15))||((p1==15)&&(p2==14))) aristas[11]=1; //verticales if(((p1==0)&&(p2==4))||((p1==4)&&(p2==0))) aristas[12]=1; if(((p1==1)&&(p2==5))||((p1==5)&&(p2==1))) aristas[13]=1; if(((p1==2)&&(p2==6))||((p1==6)&&(p2==2))) aristas[14]=1; if(((p1==3)&&(p2==7))||((p1==7)&&(p2==3))) aristas[15]=1; if(((p1==4)&&(p2==8))||((p1==8)&&(p2==4))) aristas[16]=1; if(((p1==5)&&(p2==9))||((p1==9)&&(p2==5))) aristas[17]=1; if(((p1==6)&&(p2==10))||((p1==10)&&(p2==6))) aristas[18]=1; if(((p1==7)&&(p2==11))||((p1==11)&&(p2==7))) aristas[19]=1; if(((p1==8)&&(p2==12))||((p1==12)&&(p2==8))) aristas[20]=1; if(((p1==9)&&(p2==13))||((p1==13)&&(p2==9))) aristas[21]=1; if(((p1==10)&&(p2==14))||((p1==14)&&(p2==10))) aristas[22]=1; if(((p1==11)&&(p2==15))||((p1==15)&&(p2==11))) aristas[23]=1; } Fig. 41: Funciones escritas para su utilización en el código que se encarga de dibujar las aristas.
64 Finalmente, deberá llamarse en cada ejecución del bucle principal a alguna función que muestre por pantalla las aristas dibujadas (almacenadas en el vector aristas[]) tal como se muestra en la figura 42: void muestra_aristas(){ //sumamos 4 a cada coordenada para que dibuje la línea desde el centro del sprite (de 8x8 píxeles), ya que las funciones PA_GetSpriteX() y PA_GetSpriteY() devuelven la posición de la esquina superior izquierda del mismo. if(aristas[0]==1){ PA_Draw8bitLineEx(1, PA_GetSpriteX(1,0)+4, PA_GetSpriteY(1,0)+4, PA_GetSpriteX(1,1)+4, PA_GetSpriteY(1,1)+4, 1 /* color de la línea */, 2 /* grosor de la línea */); } if(aristas[1]==1){ PA_Draw8bitLineEx(1, PA_GetSpriteX(1,1)+4, PA_GetSpriteY(1,1)+4, PA_GetSpriteX(1,2)+4, PA_GetSpriteY(1,2)+4, 1, 2); } ... } Fig. 42: Función que muestra las aristas dibujadas hasta el momento por pantalla.
65 OTRAS FUNCIONES UTILIZADAS Hasta el momento se han presentado los tres principales módulos que componen la aplicación y que mayor tiempo de trabajo han consumido. Sin embargo, ésta no estaría completa sin otras muchas funcionalidades cuya implementación ha resultado menos costosa gracias la utilización de funciones de alto nivel proporcionadas por las siguientes librerías: PALIB Mostrar texto por pantalla void PA_OutputText( screen , //Pantalla inferior o superior (0 o 1). x , //Coordenada X (0-31) del inicio del texto. y , //Coordenada X (0-31) del inicio del texto. text , //String a mostrar por pantalla. ... ) //Para mostrar variables dentro del String, usar: %s para otros strings, %d para enteros y %fX para floats con X dígitos. Ejemplo: PA_OutputText(0,2,1,1,"Me llamo %s y peso %d kilos", nombre, peso); Mostrar fondos PA_LoadBackground( screen , //Pantalla en la que mostrar el fondo (0-inferior, 1-superior). priority , //Prioridad (capa) del fondo (0 - 3). background_name ) //Fondo a mostrar. Ejemplo: PA_LoadBackground(1, 2, &pantalla_acierto);
66 Variar el brillo de la pantalla Las distintas transiciones entre pantallas se programaron variando el brillo de cada una de ellas. void PA_SetBrightness( screen , //Pantalla inferior o superior (0 o 1). bright ) //Nivel de brillo, desde -32 hasta 32, siendo el 0 neutral. Acceso al reloj del sistema Puede accederse en todo momento al reloj del sistema (por ejemplo para calcular un incremento de tiempo transcurrido) consultando las siguientes variables: PA_RTC.Day (día) PA_RTC.Month (mes) PA_RTC.Year (año) PA_RTC.Hour (hora) PA_RTC.Minutes (minutos) Generación de números aleatorios Gracias a la siguiente función, puede generarse un entero aleatorio entre otros dos enteros dados (para que, por ejemplo, varíe el orden de las preguntas en cada partida). PA_RandMinMax( min , //valor mínimo (inclusive) max ) //valor máximo (inclusive)
67 Teclado alfanumérico PAlib incorpora un teclado alfanumérico (para que, por ejemplo, un jugador introduzca su nombre) que una vez iniciado puede mostrarse y retirarse mediante las siguientes funciones... PA_KeyboardIn( x , // Coordenada X de la esquina superior izquierda del teclado. y ) //Coordenada Y de la esquina superior izquierda del teclado. PA_KeyboardOut( void ) ...pudiendo consultar la tecla pulsada en cada momento mediante la función PA_CheckKeyboard( void ). Manejo de sprites Para crear un sprite cuyo gráfico está contenido en la carpeta gfx de nuestro proyecto, utilizaremos la función... PA_CreateSprite( screen , //Pantalla en la que mostrar el sprite. obj_number , //ID del sprite a mostrar. obj_data , //gráfico correspondiente a dicho sprite. obj_shape , //especificar el tamaño en píxeles. obj_size , //especificar el tamaño en píxeles. color_mode , //(0 - 256 colores, 1 - 16 colores). palette , //Paleta a utilizar (0-15). x , // Coordenada X de la esquina superior izquierda del sprite. y ) // Coordenada Y de la esquina superior izquierda del sprite. ...pudiendo detectar en todo momento si está siendo tocado por el stylus mediante la siguiente función: PA_Sprite16cTouchedPix( sprite ) //ID del sprite a detectar.
68 LIBFAT Una vez inicializadas las librerías al comienzo del main mediante fatInitDefault(), podemos acceder a los archivos externos al ejecutable con las funciones tradicionales de manejo de ficheros en C: fopen, fclose,... ASLIB Para la reproducción de archivos de sonido en formato mp3, habrá que inicializar la librería con los siguientes parámetros... PA_VBLFunctionInit(AS_SoundVBL); AS_Init(AS_MODE_MP3); //especificamos el formato mp3. AS_SetDefaultSettings(AS_PCM_8BIT, 11025, AS_SURROUND); //parámetros //del archivo mp3. ...pudiendo comenzar la reproducción del archivo de sonido mediante las instrucciones... AS_MP3DirectPlay((u8*) nombre_del_archivo , (u32) tamaño_del_archivo ); AS_SetSoundVolume(0,127); //canal 0, volumen al máximo (0-127). AS_SetMP3Loop( true ); //el archivo se reproduce cíclicamente, de forma indefinida. ...pudiendo reproducir además los efectos sonoros, en formato raw, cuando lo deseemos, mediante la orden: AS_SoundQuickPlay( nombre_del_archivo_raw );
69
70
71 CONCLUSIONES Y POSIBLES AMPLIACIONES Una vez finalizada la aplicación, puede comprobarse con satisfacción que se han cumplido todos los objetivos recogidos en la introducción del presente proyecto. De este modo, se ha conseguido desarrollar una herramienta potente y versátil que, tal como se pretendía, resulta de gran utilidad en la educación de la visión espacial y adecuada para su uso en los centros docentes. Véanse (figura 43) algunas instantáneas de la aplicación en ejecución. Además, durante el desarrollo del presente proyecto el autor ha tomado conciencia de las dificultades que entraña la programación de aplicaciones en una plataforma tan limitada como la NintendoDS, resultando crítica la optimización en prácticamente todos los aspectos. Por otra parte, el trato continuo con el director del proyecto, y paralelamente, con los alumnos, ha resultado una experiencia altamente enriquecedora: del primero se obtuvo consejo , apoyo técnico e involucración en todo momento, y de los segundos, la sinceridad crítica, frescura de ideas y participación que sólo se obtiene de gente tan joven y que sin embargo todo usuario debería proporcionar. Sin embargo, tras la programación de la aplicación, siempre surgen nuevas ideas que merecen formar parte de la misma. Resulta necesario, por tanto, recogerlas como futuras ampliaciones, como es el caso de la implementación de un ranking donde los alumnos puedan consultar las mejores marcas obtenidas hasta el momento por el resto del alumnado, fomentando así una vez más el afán de superación a través de una sana rivalidad entre los alumnos.
78
79 Asignatura: IPM. Curso: 2010-2011. Profesor: D. Manuel Agustí. Héctor Cuñat Núñez. ANEXO I DESARROLLO DE UNA APLICACIÓN DIDÁCTICA PARA NintendoDS MEDIANTE EL USO DE LAS LIBRERÍAS Ndslib EN DevKitPro.
80 ÍNDICE I. AUTOR II. RESUMEN III. OBJETIVOS IV. REQUERIMIENTOS V. DESARROLLO Elección del dispositivo. Importación, manipulación y texturización de figuras 3D. Cargar y mostrar fondos. Integración de las distintas funcionalidades en una única aplicación. Sonido. VI. CÓDIGO FUENTE DEL PROTOTIPO. VII. CONCLUSIONES Y PROPUESTAS DE MEJORA Conclusiones. Propuesta de mejoras funcionales y técnicas. Mejoras propuestas por los usuarios. VIII. BIBLIOGRAFÍA
81 AUTOR Nombre: Héctor Cuñat Núñez Correo: [email protected] Asignatura: Integración de Medios Digitales. Titulación: Ingeniería Técnica en Informática de Sistemas. RESUMEN Aplicación didáctica para la videoconsola NintendoDS basada en la visualización y manipulación de distintos modelos tridimensionales, en la pantalla superior. Al mismo tiempo, se realizarán preguntas sobre los mismos en la pantalla inferior. La aplicación contestará, en cada caso, si la respuesta es correcta o no. OBJETIVOS No todo el mundo posee una visión espacial adecuada. Existen casos en que los tres ejes de coordenadas que se dibujan en una pizarra no son vistos espacialmente, sino como una confluencia plana de tres caminos incidentes. El presente trabajo pretende ser una herramienta didáctica que ayude a una temprana educación de la visión tridimensional, necesaria para el desarrollo personal, tanto en la vida diaria como en campos académicos: geometría, arte, arquitectura. En este plano, los objetivos son los de construir: Una herramienta didáctica sobre una plataforma lúdica. Un material utilizable en las clases de Tecnología de la ESO. Unos contenidos formadores de la educación de la visión espacial del alumnado. Esta contribución a la “didáctica del espacio”, pretende además de resultar lúdica y atrayente ser lo más viable posible. Por ello, se ha desarrollado en la plataforma NintendoDS, ya que, tras encuestar al alumnado (a un grupo de alumnos de 1º y 2º de la ESO), ésa era la consola que la mayoría poseía.
82 En el plano técnico, la aplicación desarrollada debe conseguir: La visualización y manipulación en tiempo real de modelos 3D texturizados. Una interfaz atrayente y muy usable que: Permita al usuario voltear los modelos cómodamente. Facilite responder a las preguntas formuladas de modo intuitivo y sencillo. Subraye de modo sonoro los fallos y los aciertos. REQUERIMIENTOS DevkitPro (devkitARM r32) con libnds 1.4.8. NintendoDS con cartucho para desarrollo y/o emulador. Elección del dispositivo. Debido a intereses profesionales –me dedico a la enseñanza-, desde muy temprano tuve la intención de realizar este proyecto para alguna de las videoconsolas del mercado, dada su popularidad entre el alumnado. Pronto, el campo de las posibles consolas en las que podía desarrollar la investigación propuesta, se restringió a dos: la NintendoDS o la Wii, de Nintendo. Ambas eran muy populares y tenían la propiedad de que la interacción de la videoconsola con el usuario se realizaba de una forma novedosa, cómoda e intuitiva (ya fuera con el stylus o mediante el uso del wiimote). Además, quería que mi trabajo tuviese una aplicación didáctica, que fuese una herramienta que facilitase mi trabajo como profesor de tecnología en enseñanza secundaria. Con estas premisas, realicé un boceto sobre la posible interfaz de la aplicación para cada una de las plataformas elegidas (véase la figura anexa).
83 Como muestra el texto de los bocadillos, la aplicación pensada (al menos en un principio) para reforzar el ámbito del dibujo técnico, pretende que el alumno manipule un objeto tridimensional sobre el que se realizan algunas preguntas relativas a su alzado, planta o perfil. Boceto de la aplicación para la Nintendo DS y para Wii.
84 Finalmente, consideré que dado el objetivo didáctico del proyecto, un factor clave en la decisión de la consola para la cual realizar el desarrollo debía ser la disponibilidad de la misma por parte del alumnado. Es preciso remarcar que no sólo es necesario que el alumno disponga de la videoconsola, sino también que esta esté preparada para ejecutar homebrew. Así pues, realicé una encuesta al alumnado de secundaria del CEIP Eliseo Vidal de Valencia con los siguientes resultados: Total alumnos Con NDS NDS + cartucho carga backups Wii Wii pirateada 56 48 44 18 12 100% 86% 79% 32% 21% Los resultados de la encuesta hicieron que me inclinara por la Nintendo DS, ya que, como puede verse en la encuesta, resultó que casi todos los alumnos poseían la DS y pocos la Wii. Además, el porcentaje de consolas en las que se podría ejecutar homebrew era mucho mayor en el caso de la NintendoDS. Así pues, procedí a la instalación de las herramientas de desarrollo necesarias (DevkitPro (devkitARM r32) con libnds 1.4.8. http://devkitpro.org). Con la finalidad de probar las distintas versiones de la aplicación, utilicé principalmente el emulador NO$GBA 2.6 y puntualmente una NintendoDS (modelo lite) con el dispositivo de carga de homebrew y backups, SuperCardSD. Tabla estadística DS / Wii.
85 Importación, manipulación y texturización de figuras 3D Con el objeto de tomar contacto con la funcionalidad de representar modelos tridimensionales en la pantalla de la NintendoDS, partí del ejemplo que viene con devkitpro llamado textured_quad:
86 De este ejemplo, y con la ayuda de la API de ndslib (http://libnds.devkitpro.org) comprendemos cómo implementar la funcionalidad de "pintar" en pantalla un quad y aplicarle una textura (una imagen raw de 16bits y 128x128px). Obsérvese que también se puede ver la funcionalidad de leer los botones de la consola y voltear la pieza en función de cuál esté pulsado.
87 A partir de este código, y para familiarizarme con las funciones de las librerías ndslib vistas, construí con quads un laberinto similar al del Wolfenstein3D (http://es.wikipedia.org/wiki/Wolfenstein_3D). Además, importé una textura propia (para ello me fue necesario el uso del programa bmp2bin, que convierte el mapa de bits tratado en Photoshop al formato apropiado para la NintendoDS). Sin embargo, la construcción de un modelo tridimensional especificando para cada quad las coordenadas de sus vértices resulta largo y tedioso. Por ello, Busqué una solución alternativa y descubrí que devkitpro incorpora otro ejemplo, llamado toon_shading, en el cual se importa un archivo que contiene la geometría de un modelo 3d ya creado. Además, incorpora una función (get_pen_delta()) que permite voltear el modelo desplazando el stylus sobre la pantalla táctil en lugar de presionando botones, facilidad que me pareció más usable e intuitiva. Ejemplo textured_quad de devkitpro en ejecución. Laberinto generado a partir del ejemplo anterior.
94 En la presente página, se muestran algunas de las pantallas que se visualizan al ejecutarse el programa. Para observar la ejecución completa de la aplicación desarrollada, consultése la dirección: http://www.youtube.com/wa tch?v=vaO6xPadYUk
95 Sonido Los conceptos se retienen mucho mejor cuando el emisor realza los mensajes mediante el aplauso (sonido de víctoria o éxito) y la desilusión (sonido de fracaso). Por eso, consideré importante desde el comienzo el ser capaz de incorporar sonidos al juego. Además, una tonadilla sencilla y particular sirve también para identificar a un producto por lo que también pensé que sería conveniente poseer una música de fondo que identificase de modo sonoro la aplicación. Para incorporar sonido a la aplicación, utilicé las funciones y el banco de sonidos suministrados por el ejemplo basic_sound de devkitpro.
96 Por último, es importante reseñar que dicho ejemplo hace uso de las librerías de sonido MaxMod (http://www.maxmod.org/ref/tut/dsprog.html) y que por tanto debemos modificar de nuevo el Makefile de nuestro proyecto para que las incluya.
97 CÓDIGO FUENTE DEL PROTOTIPO Tras las consideraciones anteriores, el código fuente final de la solución implementada es el siguiente:
98
99
100
101 CONCLUSIONES Y PROPUESTAS DE MEJORA Conclusiones La experiencia ha sido positiva y muy interesante, tanto por lo que he aprendido como por las posibilidades del proyecto. De hecho, lo que comenzó como un trabajo para la asignatura de IPM se ha ido perfilando como un proyecto que puede alcanzar mayor envergadura en un desarrollo posterior. En caso de abordarse, el proyecto de perfeccionamiento de la aplicación debería contener: 1) mejoras técnicas y funcionales que se me han ido ocurriendo a medida que avanzaba en su realización. 2) mejoras propuestas por los usuarios consultados. Propuesta de mejoras funcionales y técnicas Inclusión de gran variedad de figuras. Mayor versatilidad mediante la carga de archivos externos. Creación de un banco de sonidos propio. Que las preguntas salgan aleatoriamnete sin un orden definido (para que no puedan memorizarse las respuestas según el orden de aparición de las preguntas). Que haya un límite de tiempo para contestar las preguntas. Que sólo pueda darse una respuesta o que puntúen menos los aciertos después de haber fallado previamente. Que al pulsar START se pause el juego y se muestren las estadísticas y puntuaciones del jugador.
102 Mejoras propuestas por los usuarios (alumnos de Secundaria del Eliseo Vidal) Una vez finalizado el prototipo, se consultó a los alumnos del CEIP Eliseo Vidal sobre qué les había gustado y cómo les gustaría que evolucionase la apliación, recogiendo los siguientes comentarios y sugerencias: Llamarle lápiz al stylus (en general, el alumnado no interpreta qué es el stylus). Prefieren que se responda también con el stylus y no con los botones. Que la dificultad de las preguntas se reajuste según los resultados obtenidos hasta el momento. Que el jugador pueda crear un perfil al estilo de los Mii's de la Wii. Además, les gustaría que, como en algunos foros, a cada jugador se le llame de una forma según su índice de aciertos. Que el jugador se mueva por un mapa con los distintos mundos en los que se agrupen las preguntas según su temática (mundo del dibujo técnico, mundo de la electricidad,...). Que puedas acceder a una pizarrita donde hacer dibujos en sucio con el stylus.
103 BIBLIOGRAFÍA http://libnds.devkitpro.org http://devkitpro.org http://www.dev-scene.com http://www.elotrolado.net http://patater.com http://www.maxmod.org
ÍNDICE ANÁLITICO A ASLib · 20 B box modeling · 39, 40, 118 D DevkitARM · 12, 19 DevKitPro · 12, 19, 20 F flashcarts · 19, 25, 26, 76, 118, 119 frame · 15 G gameplay · 29, 30, 31, 118 L LibFAT · 20, 53, 61 LibNDS · 19 M makefile · 21, 22, 24, 118 N NeHe · 17, 77, 118 Nintendo3DS · 6, 75, 76, 119 NintendoDS · 9, 10, 11, 12, 15, 17, 18, 19, 20, 25, 42, 45, 46, 73, 75, 76, 81, 83, 84, 86, 87, 89, 92, 94, 118, 119 Notepad++ · 12, 19, 118 O OBJ · 5, 51, 53, 119 OpenGL · 12, 17, 20, 45, 46, 48, 55, 75 P PAlib · 12, 20, 21, 22, 61, 64, 69, 77 S sprites · 42, 61, 63, 64, 69, 118
T tiles · 43, 118, 119 V VRAM · 16, 42, 46, 94, 118 X xml · 59, 60, 61, 62, 63, 119
ÍNDICE DE FIGURAS Fig. 1: Alumnado del CEIP Eliseo Vidal, el cual ha sido consultado en repetidas ocasiones durante la elaboración del presente proyecto. ......................................................................................................... 7 Fig. 2: En un extremo está situado el pad direccional, en el lado contrario se sitúan cuatro botones que se corresponden con el estándar marcado por los modelos de sobremesa como SuperNintendo: X, Y, B y A, incluyendo también los botones SELECT y START (Imagen obtenida de http://zephirothspals.blogspot.com)..................................................................................................... 13 Fig. 3: Mapa de memoria de la VRAM (imagen obtenida de http://dev-scene.com). ........................... 14 Fig. 4: Al ejecutar el ejemplo 6 de NeHe, se muestran por pantalla una pirámide y un cubo girando sobre sí mismos. .................................................................................................................................... 16 Fig. 5: Resultados obtenidos en diferentes tipos de equipos. ............................................................... 16 Fig. 6: Notepad++ reconoce y colorea la sintaxis del código escrito en lenguaje C. .............................. 17 Fig. 7: Contenido de una carpeta de proyecto. ..................................................................................... 19 Fig. 8: Dentro de la carpeta gfx podemos encontrar la aplicación PAGfx, la cual nos permitirá transformar los sprites, los fondos y las texturas a un formato compatible con la NintendoDS Fig. 9: Fragmentos del makefile incluido en PALib. ............................................................................... 22 Fig. 10: Las dos flashcarts utilizadas a lo largo del presente proyecto: SupercardSD, de tipo SLOT-2 y M3iZero, de tipo SLOT-1 (Imágenes obtenidas de http://images.discoazul.com/ y http://www.dsiconsolas.com. ............................................................................................................... 23 Fig. 11: Menú del DLDIPatcher utilizado para ejecutar homebrew en la SupercardSD, la más antigua de las 2 flashcart utilizadas en el presente proyecto. ................................................................................. 24 Fig. 12: Canabalt (AdamAtomic, para navegador web y iPhone/iPod) es un juego sencillo pero extremadamente adictivo donde el jugador ha de recorrer la máxima distancia posible mientras esquiva obstáculos. Se pudo comprobar con el alumnado lo adictivo que resultaba y cómo fomentaba la competitividad por ver quién recorría mayor distancia. .................................................................... 27 Fig. 13: Esquema del gameplay de la aplicación. .................................................................................. 29 Fig. 14: Técnica similar a la descrita utilizada por Frank Miller en su novela gráfica Sin City (Imagen obtenida de http://www.mtv.com/movies). ......................................................................................... 31 Fig. 15: Bocetos que lograron una mayor aceptación entre el alumnado. ............................................ 32 Fig. 16: Dibujos coloreados en Photoshop, a partir de los bocetos realizados, para a su uso como fondos en la aplicación .......................................................................................................................... 33 Fig. 17: Creación de las referencias artísticas en el paquete de modelado 3D. ..................................... 37 Fig. 18: Proceso de modelado del telescopio mediante la técnica de box modeling. ........................... 38 Fig. 19: Laberinto similar al del juego Wolfenstein3D (ID software, 1992) formado por una serie de quads texturizados. ............................................................................................................................... 39 Fig. 20: Modelos empleados en la aplicación, mostrando su sencilla malla geométrica. ...................... 39 Fig. 21: Ahorro de memoria en la textura realizando un mirroring del modelo. ................................... 40 Fig. 22: Uso de tiles en la texturización del planeta. ............................................................................. 41 Fig. 23: Se pretendió que la lente del observatorio tuviese especial detalle. ........................................ 41
Fig. 24: Modelos con sus correspondientes texturas, mostrando el tamaño relativo de éstas y el banco de memoria en el que se ubican. ........................................................................................................... 42 Fig. 25: Frontend 'NDSModelExporter', de Kasikiare que proporciona una sencilla interfaz Java a los 2 programas nombrados. ......................................................................................................................... 43 Fig. 26: Código que muestra por pantalla un modelo con su correspondiente textura. ....................... 45 Fig. 27: Fragmento de código que mostraría el desplazamiento del modelo00 a lo largo del eje X y del modelo01 a lo largo del eje Y. ................................................................................................................ 46 Fig. 28: Animación de 20 fotogramas que reproducidos alternativamente en sentidos contrarios (del 1 al 20, del 20 al 1, del 1 al 20, del 20 al 1...) provocan la sensación de carrera del protagonista. .......... 47 Fig. 29: Contenido del archivo cubo.obj. ............................................................................................... 50 Fig. 30: Código de la función encargada de cargar los *.obj externos al ejecutable. ............................ 52 Fig. 31: La aplicación texturiza automáticamente la figura importada, aplicándole a cada cara una textura predefinida y aprovechando así una vez más las ventajas ofrecidas por el uso de tiles. .......... 53 Fig. 32: Código que muestra por pantalla la figura cargada. ................................................................. 54 Fig. 33: Imagen del exportador de OBJ's incluido en 3DSMAX, donde se especifica que el *.obj creado esté formado únicamente por quads. ................................................................................................... 55 Fig. 34: Parámetros utilizados en la exportación de OBJs, en Blender . ................................................ 56 Fig. 35: Sintaxis del XML que contiene los enunciados y las soluciones. ............................................... 57 Fig. 37: Identificación de los posibles vértices y aristas que forman la vista solución. .......................... 58 Fig. 36: Sintaxis del XML que contiene los enunciados y las soluciones. ............................................... 58 Fig. 38: <aristas>1 1 1 1 1 1 0 1 0 1 1 1 1 0 0 1 1 1 1 1 1 0 0 1</aristas> ... 59 Fig. 39: Código de la función encargada de leer el xml con los enunciados y las soluciones................. 61 Fig. 40: Código que detecta qué vértices está uniendo el jugador con el stylus. .................................. 62 Fig. 41: Funciones escritas para su utilización en el código que se encarga de dibujar las aristas. ....... 63 Fig. 42: Función que muestra las aristas dibujadas hasta el momento por pantalla. ............................ 64 Fig. 43: Distintas imágenes que muestran la aplicación en ejecución. .................................................. 72 Fig. 44: Foto de la Nintendo3DS, de aspecto muy similar a los últimos modelos de NintendoDS Fig. 45: Listado comprobado de flashcarts compatibles hasta el momento con la Nintendo3DS según www.elotrolado.net ............................................................................................................................... 74