scieee AI-readable full text Open interactive document viewer

Desarrollo de un videojuego empleando RT-DESK con XNA y C#

Torres Martínez, Carlos

Abstract

Mediante la creación de un videojuego y su adaptación a la tecnología RT-DESK, basada en la simulación discreta de eventos y creada en la universidad politécnica de Valencia, se ha buscado tanto formarse en la creación de los mismos como en contribuir a la investigación de la nueva tecnología y su aplicación a los videojuegos. La descripción del trabajo realizado en la programación del videojuego y que se encuentra en esta memoria puede servir de ayuda para aquellos que tengan intención de iniciarse en la creación de videojuegos. Por su parte, la posterior adaptación a la tecnología RT-DESK y el análisis comparativo entre ambas versiones del videojuego han revalidado la capacidad de dicha tecnología y sus posibilidades frente al bucle principal convencional.

Full text

Escuela Técnica Superior de Ingeniería Informática Universidad Politécnica de Valencia Desarrollo de un videojuego empleando RT-DESK con XNA y C# Proyecto final de carrera Licenciatura en ingeniería informática Septiembre 2015 Autor: Carlos Torres Martínez Director: Ramón Mollá Vayá 2 A todos los que han fomentado y apoyado mi pasión por los videojuegos. 3 Índice Resumen ................................................................................................................................... 5 Estructura de la memoria........................................................................................................... 6 Introducción ............................................................................................................................... 7 ¿Qué es un videojuego?..................................................................................................... 7 La industria del videojuego ................................................................................................. 8 El auge del videojuego independiente................................................................................. 9 Objetivo.................................................................................................................................10 Creación de un videojuego ................................................................................................10 Port a la tecnología RT-DESK............................................................................................10 Motivación.............................................................................................................................10 Metodología ..........................................................................................................................11 Estado del arte..........................................................................................................................13 Estado del arte..........................................................................................................................13 El bucle principal ...................................................................................................................13 Motores y librerías.................................................................................................................14 Precedentes, el género shoot ‘em up ....................................................................................15 Análisis .....................................................................................................................................16 Requisitos .............................................................................................................................16 Planificación temporal ...........................................................................................................17 Tecnología escogida..........................................................................................................18 Otras herramientas ............................................................................................................19 Diseño ......................................................................................................................................22 Diseño UML...........................................................................................................................22 Menú principal.......................................................................................................................23 Implementación.........................................................................................................................24 Carga de assets ....................................................................................................................24 Sprites...................................................................................................................................25 Sprite sheet........................................................................................................................25 Dibujado de sprites ............................................................................................................26 Orden de dibujado .............................................................................................................27 Color key............................................................................................................................27 Animación..........................................................................................................................27 Problema al dibujar sprites: Artefactos...............................................................................29 Gestión de la entrada ............................................................................................................30 Colisiones..............................................................................................................................32 Personaje controlado por el jugador......................................................................................33 Desplazamiento.................................................................................................................33 Disparo ..............................................................................................................................33 Escudos, absorción y sobrecalentamiento.........................................................................34 Teletransporte....................................................................................................................34 Sombra..............................................................................................................................35 Fondos..................................................................................................................................36 4 Mapa de tiles .....................................................................................................................36 Animación..........................................................................................................................37 Lectura de un fondo de fichero...........................................................................................37 Fondo procedural...............................................................................................................37 Niveles ..................................................................................................................................39 Nivel procedural.................................................................................................................39 Nivel creado a mano..........................................................................................................39 Subsistema de audio.............................................................................................................40 AudioManager ...................................................................................................................41 Efecto de fade....................................................................................................................42 Cadencia de sonidos .........................................................................................................43 Menús ...................................................................................................................................44 Diseño ...............................................................................................................................44 Fuente ...............................................................................................................................45 Simulación discreta desacoplada..............................................................................................46 RT-DESK ..............................................................................................................................46 Evolución de RT-DESK......................................................................................................46 Funciones principales ........................................................................................................47 El bucle principal en RT-DESK..............................................................................................47 Acople de RT-DESK y XNA...................................................................................................48 Adaptación C# y C++.........................................................................................................48 Adaptación de la clase Game ............................................................................................48 Pruebas.................................................................................................................................49 Entorno de pruebas ...........................................................................................................49 Diseño de las pruebas .......................................................................................................49 Resultados.........................................................................................................................50 Conclusiones ............................................................................................................................52 Relación del trabajo con estudios cursados...........................................................................52 Trabajos futuros........................................................................................................................54 Agradecimientos .......................................................................................................................55 Glosario ....................................................................................................................................56 Fuentes.....................................................................................................................................57 Anexo A: GDD ..........................................................................................................................58 5 Resumen Mediante la creación de un videojuego y su adaptación a la tecnología RT-DESK, basada en la simulación discreta de eventos y creada en la universidad politécnica de Valencia, se ha buscado tanto formarse en la creación de los mismos como en contribuir a la investigación de la nueva tecnología y su aplicación a los videojuegos. La descripción del trabajo realizado en la programación del videojuego y que se encuentra en esta memoria puede servir de ayuda para aquellos que tengan intención de iniciarse en la creación de videojuegos. Por su parte, la posterior adaptación a la tecnología RT-DESK y el análisis comparativo entre ambas versiones del videojuego han revalidado la capacidad de dicha tecnología y sus posibilidades frente al bucle principal convencional. 6 Estructura de la memoria En primer lugar se puede encontrar una introducción al proyecto, donde se describe brevemente y justifica su desarrollo y la motivación detrás del mismo, además de describir el contexto en el que se realiza y aclarar algunos conceptos básicos y necesarios para la comprensión de los siguientes apartados. A continuación se analiza el estado del arte, tanto de los videojuegos como de la creación de los mismos y las tecnologías que los apoyan, así como los precedentes que sentaron las bases y fueron inspiración del proyecto. En el apartado de análisis se analiza el problema y se planifica el trabajo que conlleva y habrá que realizar, así como una justificación de las herramientas a usar. En el siguiente apartado, implementación, se detallan las diferentes soluciones llevadas a cabo para las diferentes partes del videojuego. En RT-DESK se trata la segunda parte del proyecto, la adaptación a RT-DESK, donde se explica de qué trata la tecnología así como el proceso realizado al adaptar el juego a la nueva tecnología, y además se aporta un análisis comparativo entre ambas versiones. Para acabar, en conclusiones se encuentran la valoración y consideraciones finales, tanto acerca del trabajo realizado como de la utilidad de las tecnologías usadas y su aplicación en futuros proyectos. La memoria se cierra con un pequeño glosario, la bibliografía consultada y el documento de diseño de juego, anexo A, del videojuego implementado. 7 Introducción ¿Qué es un videojuego? Un videojuego (A veces abreviado simplemente como “juego”) es un juego electrónico en la que el jugador, a partir de una información principalmente visual y sonora, toma decisiones y las transmite mediante un dispositivo de entrada. La creación de un videojuego está muy relacionada con artes como la música, la pintura o la escritura, pero es esa interacción entre juego y el jugador la que lo define y diferencia del resto de medios de expresión. Lanzado por la compañía Nintendo para la consola NES en 1988, Super Mario Bros. 3 se trata de uno de los videojuegos de mayor éxito. 8 La industria del videojuego El origen de los videojuegos se remonta a la década de los cincuenta, pero no fue hasta los setenta cuando el descenso en los costes del hardware permitió su comercialización y expansión entre el público, propiciando la creación de una industria y su desarrollo. Además de funcionar sobre ordenadores personales, surgieron videoconsolas, sistemas cerrados pensados para la ejecución de videojuegos, lo cual permitió tanto reducir los costes de fabricación y venta de los sistemas, así como facilitar su uso, acercando los videojuegos a un mayor número de personas. De entre las diferentes industrias enfocadas al entretenimiento, los videojuegos ha sido la que más ha crecido en los últimos años, llegando a suponer un volumen de negocio superior al del resto de industrias 1 . Por otro lado, la llegada y expansión del sector móvil y el videojuego social ha hecho que la cantidad de clientes potenciales aumente drásticamente, y las nuevas generaciones nacen y crecen conociendo el concepto de videojuego. Así pues, estamos en un punto en el que los videojuegos se han convertido en un medio de expresión y una forma de ocio enormemente aceptada y extendida. Miles de millones en ventas de videojuegos en Estados Unidos 2 . El diseño de videojuegos ha estado influenciado por las limitaciones que imponía la tecnología de cada época, como limitaciones de memoria o de procesamiento. El avance tecnológico ha ido acabando con dichas limitaciones y permitiendo, por ejemplo, el salto de los videojuegos en 2d a los 3d. El mayor detalle en la recreación que la tecnología va permitiendo está estrechamente relacionado con los costes de desarrollo necesarios para aprovecharla, los cuales se han visto incrementados de forma drástica 3 . 1 http://www.fastcompany.com/3021008/why-video-games-succeed-where-the-movie-and-musicindustries-fail 2 http://www.theesa.com/wp-content/uploads/2015/04/ESA-Essential-Facts-2015.pdf 3 http://kotaku.com/how-much-does-it-cost-to-make-a-big-video-game-1501413649 9 El auge del videojuego independiente Si bien el aumento en los costes que suponía desarrollar para una tecnología más avanzada propició, en las décadas de los ochenta, noventa y el nuevo siglo, que cada vez más pequeñas empresas no pudiesen competir en el sector comercial, ha sido ese mismo avance en las tecnologías, de comunicaciones en este caso, lo que permitió la creación de webs donde colgar juegos (Newgrounds, Kongregate, etc.) aunque con escasa o nula repercusión comercial, y posteriormente plataformas de distribución y venta digital, las cuales han permitido disminuir esos costes de distribución y llegar a un mayor público, así como darle a los desarrolladores más pequeños la posibilidad de distribuir comercialmente sus juegos, dando lugar a un nuevo auge del videojuego independiente. Algunas de las primeras plataformas de distribución digital de videojuegos fueron Steam 4 , creada por la compañía Valve en el año 2004, o el servicio Xbox Live Arcade para consolas de Microsoft. El auge del videojuego independiente y su presencia en la primera línea de la industria ha fomentado tanto la innovación como la recuperación de diferentes tipos de videojuegos que se fueron dejando atrás según la tecnología avanzaba, debido a la mayor oportunidad de estos de encontrar su público y al menor riesgo económico que supone lanzar un juego en una plataforma de distribución digital. Cave Story, creado por Pixel 5 en el 2004, se trata de uno de los primeros y mejor valorados juegos de este nuevo auge del videojuego independiente. 4 http://store.steampowered.com/ 5 http://studiopixel.sakura.ne.jp/ 16 Análisis Requisitos Los requisitos que debe cumplir el proyecto son:  Gestión de los gráficos. El juego deberá cargar los assets gráficos que se usaran en el juego, así como controlar la correcta visualización y animación de estos.  Subsistema de control de Audio. Debe permitir gestionar los efectos y la música y permitir controlar su reproducción (Reproducir, pausar, cortar, aplicar efectos de fundido y controlar la repetición de sonidos.)  Subsistema de control de la entrada. Debe proveer de un control y gestión de los dispositivos de entrada usados en el juego, mando y teclado, para facilitar el manejo de la interacción del jugador.  Menús. Implementar un sistema para introducir un menú de juego con diferentes pantallas y diferentes opciones, así como permitir hacer uso del mismo APRA cambiar diferentes características del juego (como podría ser el idioma, el nivel a jugar, etc.).  Gestión de pantallas de arranque. Proveer de un sencillo sistema que permita controlar las pantallas de arranque del juego, ya sea para mostrar el nombre del estudio creador, de las tecnologías empleadas y demás información necesaria.  Gestión de puntuaciones. Como en la mayoría de juegos del género, la competición entre jugadores por alcanzar las máximas puntuaciones es uno de los puntos fuertes que invita a rejugar y mejorar. El juego permitirá introducir a los jugadores su puntuación, si esta se encuentra entre las diez mejores, así como sus iniciales. Además, el menú de opciones contará con una opción para resetear la tabla.  Personaje principal. El personaje principal podrá moverse libremente en cualquier dirección usando el stick analógico del mando, lo cual es un punto fuerte respecto al movimiento discretizado a 8 direcciones de otros juegos, especialmente en PC al estar pensados para ser jugados mediante un teclado y que el mayor número de personas puedan jugarlo. También podrá disparar en diferentes direcciones, no solo en una como es habitual, y esta dirección de disparo será independiente de la dirección del movimiento de la nave, como se puede ver en juegos como Geometry Wars o Smash TV.  Gestión de enemigos e incluir diferentes tipos.  Gestión de disparos e incluir diferentes tipos.  Fondos y gestión de estos. No tanto por una decisión de diseño como por el ánimo de aprender, el juego contará con al menos dos tipos de fondos, uno creado a partir de un mapa de tiles y otro generado proceduralmente.  Gestión de niveles. 17 El juego contará con diferentes fases y jefes, el jugador podrá jugarlos en orden en el modo historia o seleccionar uno de ellos en el modo de prueba. Se ha incluido está opción para facilitar mostrar el trabajo realizado en el PFC a aquellas personas que no cuenten con la habilidad o el tiempo suficiente para avanzar en el modo historia. Para más detalle sobre los requisitos del videojuego consultar el GDD en el Anexo A. En cuanto a requisitos tecnológicos, básicamente se necesita que la tecnología escogida como base del juego debe de ser compatible con RT-DESK. Planificación temporal La planificación temporal realizada a partir de los requisitos del juego así como de las fases necesarias en la creación de un videojuego: 18 Nota: Aunque no está indicado en el diagrama y como se ha mencionado anteriormente, durante los meses anteriores se realizaron una serie de prototipos que concluyeron con un brainstorming final para decidir qué entraba y qué no y la descripción final del videojuego en un GDD. Diagrama de Gantt. Herramientas Tecnología escogida A la hora de escoger la tecnología que serviría de base al videojuego se tuvieron en mente una serie de consideraciones: Partir de un nivel más bajo usando librerías como XNA o SDL para construir uno mismo la base sobre la que funciona del videojuego tiene dos principales ventajas: El mejor aprendizaje del funcionamiento interno de un videojuego y la libertad que ofrece no estar limitado a las posibilidades de un motor concreto. Sin embargo, para que esa “libertad” extra que se tiene pueda dar sus frutos es necesario un gran trabajo y no suele merecer la pena: Hoy en día los motores de juegos ofrecen opciones más que suficientes para desarrollar casi cualquier videojuego y el ahorro en tiempo resulta enorme. Así pues, una de las principales razones por las que se optó por partir de una librería es la voluntad de aprender y hacerse una idea, al dar el salto a un motor en un futuro, del funcionamiento interno de estos. De entre las librerías que se consideraron, como SDL, SFML o XNA, finalmente se optó por XNA, en su última versión 4.0, por los conocimientos previos que se tenían del lenguaje C# requerido por esta así como por experiencias previas con ella que facilitarían el desarrollo del proyecto. Además, la tecnología XNA cumple el requisito de ser compatible con RT-DESK, compatibilidad que fue fruto de un trabajo de final de carrera anterior y del que se parte y busca expandir su documentación. 19 Otras ventaja, compartidas por las otras librerías mencionadas, es que todas son de uso gratuito. Las principales desventajas de XNA frente al resto son, en primer lugar, que su uso se reduce a dispositivos Microsoft, al contrario que las demás que funcionan en una variedad más amplia de dispositivos. Sin embargo, no siendo el objetivo el lanzamiento comercial del juego y no queriendo centrarse en el desarrollo de versiones para diferentes sistemas sino en el aprendizaje en sí, no resultó un inconveniente. El otro inconveniente es que su desarrollo se ha descontinuado, y no se parece que Microsoft vaya a dar más soporte a este tecnología. Aún así, cabe destacar como ventaja de XNA el desarrollo paralelo que se realizó de forma libre para adaptarla a diferentes plataformas, dando como resultado la tecnología MonoGame 10 . De esta forma, una vez completado su desarrollo la compatibilidad del código realizado con XNA será totalmente compatible con MonoGame permitiendo, hipotéticamente, lanzar versiones del proyecto para sistemas operativos como Linux o consolas que no sean de Microsoft. Otras herramientas Para el desarrollo del proyecto se ha optado por el uso de herramientas gratuitas, con la excepción de Microsoft Office y RT-DESK. La lista de herramientas usadas es la siguiente: 10 http://www.monogame.net/ 20 Visual Studio, el IDE (Integrated development environment) de Microsoft con integración con XNA, lo que lo convierte en la opción ideal. Uno de sus puntos fuertes sobre sus competidores es su robustez y su depurador. RT-DESK 11 (Real Time Discrete Simulation Kernel) es una librería desarrollada en la UPV y diseñada para la gestión temporal de eventos discretos en tiempo real. Ofrece todas las ventajas de la simulación discreta pero además sincroniza la simulación con el tiempo real durante su ejecución. Es una herramienta enfocada tanto para el desarrollo de aplicaciones en tiempo real como pueden ser videojuegos, simuladores de entrenamiento, realidad virtual o realidad aumentada, como para modelar sistemas que estén descritos como una colección masiva de objetos simples que interactúen unos con otros como pueden ser la simulación de partículas o los autómatas celulares. En este proyecto, concretamente, se usará una versión para C# y previamente probada con XNA. Google Docs y Microsoft Word, editores de texto usados para la creación de toda la documentación relativa al proyecto. Si bien Google Docs permite copias de seguridad en la nube que pueden ser modificadas desde cualquier lugar con internet usando una interfaz cómoda y simple, la ausencia de algunas opciones (Por ejemplo, índices que referencien el número de página de cada apartado ) hacen que sea necesario terminar los documentos usando Microsoft Word. Se ha utilizado OpenOffice Calc, una herramientas gratuita para la edición de hojas de cálculo, para la manipulación de los datos recogidos de los tests y su representación en gráficas. ArgoUML 12 , editor UML libre usado en la creación de algunos de los diagramas usados en la documentación. Una de las ventajas frente a sus competidores es que no requiere de una inscripción para su uso ni limita su funcionalidad en su versión gratuita. La versión para escritorio ofrece las herramientas necesarias para este proyecto. Tiled 13 , un editor de mapas de tiles, se usará para facilitar la generación de mapas de tiles usados para probar dicha funcionalidad del proyecto. Paint y Gimp 14 , editores de imágenes utilizados en la creación y edición de los assets gráficos necesarios para el juego. Paint ofrece una solución rápida y cómoda de editar imágenes a nivel de píxel, ideal para videojuegos sencillos en 2D a baja resolución, pero lo limitado de sus opciones hacen que para realizar una edición más compleja, si esta fuese necesaria, se opte por Gimp. 11 http://rtdesk.blogs.upv.es/ 12 http://argouml.tigris.org/ 13 http://www.mapeditor.org/ 14 http://www.gimp.org/ 21 Además, también se hará uso de GraphicsGale 15 para facilitar la animación de los mismos al permitir ver el resultado y modificarlo en tiempo real, además de traer una serie de opciones pensadas específicamente para crear y probar animaciones, como el efecto cebolla entre frames o modificar parámetros como la velocidad de cada frame de forma cómoda para hacerse una mejor idea de cómo quedará la animación dentro del juego. Para la creación de efectos de sonido, aparte del uso de efectos y música libre, Bfxr 16 ofrece una solución ideal, pues permite crear sonidos de diferentes tipos (de salto, de disparo, etc.) forma aleatoria hasta encontrar uno que sea adecuado para el juego, sin necesidad de tener conocimiento alguno acerca de la creación de sonidos. Además, también permite variar algunos parámetros a aquellas personas que sepan algo o simplemente quieran curiosear. Para la edición de los sonidos, como recortar o editar para facilitar su reproducción en bucle, se utilizará Audacity 17 , un editor gratuito de sonido que destaca por su sencillez y variedad de opciones y que además fue el usado durante la carrera en diferentes asignaturas de sonido. 15 http://www.humanbalance.net/gale/us/ 16 http://www.bfxr.net/ 17 http://audacityteam.org/ 22 Diseño Diseño UML Diagrama UML. 23 Menú principal Esquema del menú principal del juego. Tras pasar las pantallas de introducción (Desarrollador, tecnologías empleadas, etc.) la pantalla en la que el jugador recibe el control del juego es la pantalla de título de juego, también llamada pantalla de “press start”, en la que se muestra el título del juego. Desde ella se accede únicamente a la pantalla principal, desde donde puede comenzar una partida en al juego en el modo historia, acceder a las tablas de puntuaciones y a los menús de pruebas y opciones. El menú de pruebas permite al jugador jugar una fase cualquiera, además de permitirle seleccionar qué fondo quiere usar para la partida. En el menú de opciones se encuentra la opción de borrar la tabla de puntuaciones y devolverla a su estado original, además del tutorial donde se explica el funcionamiento del juego y los créditos, que incluyen el nombre del alumno, del director de proyecto, tecnologías empleadas y agradecimientos. Además, la opción de borrar puntuaciones lleva a una pantalla de confirmación, para evitar que el jugador pueda borrar sus puntuaciones por equivocación. Tras acabar una partida (Jugar) el juego vuelve a la pantalla de puntuaciones. 24 Implementación Carga de assets Los assets de un videojuego son sus recursos visuales y sonoros, tales como texturas, modelos o efectos de sonido. Para que el juego pueda hacer uso de ellos XNA provee de un content pipeline 18 , que en el momento de la compilación se encarga de procesar los assets a un formato que el juego pueda reconocer y acceder a ellos mediante un content loader en el framework. Diagrama del proceso de carga de assets en XNA. El propio Visual Studio se encarga de, al generar una nueva solución de XNA, crear dos proyectos distintos, uno para la lógica de juego y otro para el contenido, donde a su vez crea una carpeta para los ficheros de audio, para los ficheros de imagen, etc. que el juego va a acceder posteriormente y añadirlos es tan sencillo como copiarlos en su carpeta correspondiente e indicárselo a visual Studio usando su navegador de archivos (o refrescar la carpeta). Para acceder a ellos utilizamos el método load de la clase ContentManager, una instancia de la cual, Content se encuentra en la clase Game, por ejemplo: Content.Load<Texture2D>(@"Images/textura") Nótese que hace falta indicar el tipo de formato del asset a cargar (Texture2D para imágenes o SoundEffect para efectos de sonido), además de que no se indica la extensión del fichero. Esto se debe a que en XNA los assets se referencian mediante una cadena identificadora que por defecto es el nombre del fichero sin la extensión, no por el nombre de fichero. Los formatos aceptados por XNA son limitados, aunque ofrece la posibilidad de añadir soporte para nuevos formatos. En este proyecto sin embargo se ha limitado su uso a los primeros, .png o .bmp para las imágenes y .wav para los efectos de sonido y música. 18 https://msdn.microsoft.com/en-us/library/bb447745.aspx 25 Sprites Un sprite es un gráfico 2d usado para representar visualmente los elementos del juego. Objetos, enemigos o el personaje principal entre otros. Por ejemplo: Sprite de Mario del juego Super Mario bros. Sprite sheet Los sprites se almacenan en una Imagen donde se guardan los diferentes frames que forman las animaciones de los elementos de un juego. Qué se guarda en cada sprite sheet puede variar según las preferencias de cada uno, pero una práctica extendida suele ser crear un sprite sheet por elemento (Por ejemplo, uno solo para el personaje principal), poniendo en cada fila los frames correspondiente a una acción o estado (Por ejemplo, estar quieto, correr o saltar): Parte del sprite sheet de Mario del juego Super Mario bros. Para facilitar su uso generalmente cada frame se guarda y separa del resto usando un tamaño normalizado, de forma que se pueden dibujar en pantalla haciendo uso del mismo atributo de posición. Se considera por defecto el inicio del sprite su esquina superior izquierda, para acceder a un sprite tenemos que conocer dicha posición y el tamaño del sprite. Al ser los sprites de un tamaño fijo obviamente conocemos dicho tamaño y a partir de él obtenemos la posición del sprite: Posición X en el sprite sheet = frame de la animación * ancho de sprite Posición Y en el sprite sheet = ID del estado del sprite * alto de sprite 32 Colisiones Algunos de los elementos del juego pueden colisionar entre ellos, por ejemplo, las balas de la protagonista con las naves enemigas. Para comprobar las colisiones existen diferentes técnicas, siendo la colisión por cajas y la colisión por píxel las más usadas en los juegos en 2D del género. La colisión por cajas consiste en asignar una o más cajas de colisiones a los objetos, y calcular la colisión entre estas cajas. Al asignar las cajas se trata de ajustar a la forma irregular del sprite una forma sencilla (un cuadrado o un círculo, por ejemplo), simplificando el problema de las colisiones. Ejemplo de caja de colisiones rectangular para el sprite de Mario. A un mismo objeto se le pueden asignar varias cajas, ya sea porque una única forma básica no es suficiente o porque diferentes partes del objeto tienen comportamientos diferentes. Un ejemplo de esto último sería un enemigo al que puedes dañar y destruir diferentes partes, de forma que cada parte necesita su propia caja de colisiones. Para calcular la colisión entre dos cajas rectangulares, las únicas usadas en el proyecto, se usa la siguiente fórmula: if(A.x + A.cajaAncho >= B.x + B.cajaInicioX && A.x + A.cajaInicioX <= B.x + B.cajaAncho && A.y + A.cajaAlto >= B.y + B.cajaInicioY && A.y + A.cajaInicioY <= B.y + B.cajaAlto) colision = true; else collision = false; En algunos casos en los que se busca una mayor precisión se emplea la técnica de colisión por pixel, que consiste en detectar pixel a pixel (o pixel con una caja de colisiones) si dos objetos colisionan entre sí. Aún así, se trata de una técnica que requiere de un gran coste de cálculo, así que en la práctica, de usarse, primero se descarta la colisión mediante la técnica de caja de colisiones. Por ejemplo, se calcula la colisión del personaje con todas las balas enemigas, y únicamente si se detecta colisión con una, se mira la colisión por píxel entre dicha bala y el personaje. 33 Personaje controlado por el jugador El jugador controla un único personaje, una nave espacial. La especificación de dicho personaje se encuentra en el anexo, la implementación de la cual se detalla a continuación. Sprite de la nave controlada por el jugador. Desplazamiento El desplazamiento de la nave puede ser en cualquier dirección (360º) y a diferentes velocidades. Para conseguir esto se hace uso de uno de los sticks del mando (concretamente el izquierdo), ya que permite la entrada de la dirección (stick analógico de 360º, como el movimiento que se busca permitir realizar) y diferentes grados de inclinación para cada dirección, lo cual se usa para controlar la velocidad del personaje. En XNA el estado del stick viene dado por coordenadas dentro un círculo unitario. Así, en reposo el stick se encuentra en la posición (0,0), y si se inclinase por completo hacia la derecha, se encuentra en la posición (1,0). De esta forma, la velocidad de la nave en el juego está controlada por la posición del stick en cada coordenada, en tanto que esta representa la inclinación del stick. A más presión del jugador sobre el stick, más inclinación y, por tanto, más velocidad. Sin embargo, se ha establecido una mínima inclinación del stick a partir de la cual se empieza a mover la nave, para evitar que esta lo haga debido a posibles leves inclinaciones causadas por presión ejercida por el pulgar del jugador al reposar sobre el stick. Además, la velocidad máxima a la que puede moverse la daba es superior al máximo valor de inclinación (1), así que este se extrapola de [0,1] al rango [velocidad mínima, velocidad máxima]. Disparo Al contrario que el movimiento analógico de la nave, se ha discretizado las direcciones a las que puede disparar, limitándose a 8 (arriba, abajo, izquierda, derecha y las cuatro diagonales entre ellas). El jugador escoge en qué dirección quiere disparar usando los cuatro botones posteriores, los cuales generalmente se disponen formando un “rombo”, quedando uno arriba, uno abajo, otro a la izquierda y el último a la derecha. Así, cada uno de estos botones sirve para disparar en la dirección en la que se encuentran. Por ejemplo, con el botón superior el jugador puede disparar hacia arriba, y con el derecho hacia la derecha, además de poder pulsar dos botones adyacentes para disparar en diagonal, por ejemplo, pulsando los botones superior y derecho dispara en diagonal la diagonal formada por ambos botones, arriba hacia la derecha. Debido a la dificultad de pulsar dos botones al mismo tiempo al tratar disparar en diagonal, se ha dejado un tiempo, muy pequeño, desde que se pulsa uno de los botón de disparo hasta que la nave dispara en el juego, evitando que al disparar en diagonal la mayoría de veces dispare unas pocas balas en una dirección que no es la deseada. 34 Una vez se ha pulsado un botón de disparo, la nave dispara. Esto implica que desde que la nave empieza a disparar hasta que se suelta se crean balas en un intervalo predeterminado (dos balas en paralelo en cada intervalo) cuya dirección es la dirección de disparo descrita anteriormente, sobre las cuales el jugador ya no tiene control alguno y sobre las que se entra en detalle más adelante. Además, hay que tener en cuenta que al disparar en una dirección se rota el sprite de la nave protagonista para que encare dicha dirección, la cual no cambia hasta que no se dispare en otra dirección. Escudos, absorción y sobrecalentamiento La nave cuenta con dos escudos, de color verde y azul, usados para absorber las balas de su mismo color al entrar en contacto con ellas y evitar el daño. Al pulsar el botón asignado a un escudo, este se activa. Aparece alrededor de la nave protagonista suavemente, de ser invisible a totalmente visible, efecto para el cual se ha usado la función de dibujado Draw descrita en el apartado de dibujado de sprites. Básicamente, el parámetro Color indica el color del que se tinta la imagen a dibujar (White para usar el color original), y si este parámetro es multiplicado por un float entre 0 y 1 se puede alterar la transparencia de lo que se dibuja. De esta forma multiplicamos dicho Color por una variable de tipo float donde almacenamos el nivel de transparencia, los valores de la cual parten de 0 (o el valor actual de la transparencia, si dejamos de pulsar y los encendemos rápidamente antes de que se apaguen) al encender el escudo hasta que alcanzan su valor máximo 1. Al soltar los escudos se apagan, con un efecto de desaparición opuesto al mencionado. Los escudos se guardan como un sprite que almacena el contorno de la nave en el color del escudo, de forma que basta con dibujarlo en la misma posición en la que se dibuja la nave. Como dice la especificación del juego, si se mantiene encendido el escudo cierto tiempo la nave se sobrecalienta. Se avisa poco antes de que esto ocurra cambiando el color del escudo a rojo (además de contar con una señal sonora). En caso de que se sobrecaliente no se permite volver a activar los escudos hasta que pase el efecto, el cual visualmente se ha representado “tintando” el sprite de color rojo usando la funcionalidad que para ello ofrece la función Draw descrita en el apartado de dibujado de sprites, concretamente haciendo uso del parámetro Color, asignando Color.Red. Teletransporte Otra de las habilidades con las que cuenta el jugador es la posibilidad de teletransportarse una distancia fija en cualquier dirección, esquivando los elementos que haya entre la posición original y la posición destino. La nave se teletransporta en la dirección del movimiento, por lo tanto al igual que el desplazamiento básico se trata de un movimiento que puede realizarse en cualquiera de los 360º. Sin embargo, al tratarse de una distancia fija, esta no depende de cuando se presione el stick, con lo cual hay que sacar el vector unitario que define la dirección del punto en el que se encuentra el stick. Para ello es suficiente con dividir cada componente 35 del par de componentes X e Y que definen la posición del stick por el módulo del vector que va del origen a dicho punto. Efecto visual al teletransportarse. Visualmente se ha creado un efecto de teletransporte que consiste en que la nave deje un rastro, intentando simular un efecto de desplazamiento a gran velocidad. Dicho rastro consiste en una serie de impresiones en pantalla del mismo sprite de la nave, pero más transparentes cuanto más lejos se encuentran. Las posiciones de estas impresiones, al encontrarse en la misma línea que va del punto original al punto destino de teletransporte se calculan, pues, de la misma forma que se calcula este último, pero decrementando el valor de la distancia de teletransporte por el intervalo que separa las diferentes impresiones (Así como el propio valor de la transparencia). Sombra Existe un efecto meramente visual, que no repercute en la jugabilidad, que consiste en la proyección de una sombra sobre el suelo o los elementos que se encuentren por debajo de la nave protagonista. Dicha sombra consiste simplemente en un sprite de color oscuro que se imprime de forma semitransparente sobre los elementos correctos. Dichos elementos son aquellos que, al encontrarse por debajo de la nave, se dibujan con un valor de profundidad (o layer depth) mayor, y por tanto automáticamente XNA se encargará, al ordenar e imprimir en pantalla, de dibujar la sombra únicamente sobre estos. La sombra se mueve por una subregión de la pantalla, la cual se encuentra en el centro y tiene la misma forma de la pantalla de juego (equidistando los lados de esta subregión de los lados de la pantalla). Dicha posición depende de la posición de la nave, conociendo esta sacamos la posición de la sombra con la siguiente fórmula: Sombra.pos.X = subregión.posInicial.X + nave.pos.X * (subregión.ancho / pantalla.ancho) Sombra.pos.Y = subregión.posInicial.Y + nave.pos.Y * (subregión.alto / pantalla.alto) 36 Fondos Qué es un mapa o nivel en un juego depende de cada juego, de su definición y requisitos. En este proyecto no existe interacción entre los objetos (Personaje principal, enemigos, etc.) y el escenario, de forma que se han tratado de forma independiente, reduciendo el concepto de escenario al de fondo, un elemento puramente estético. Existen diferentes opciones a la hora de crear fondos para videojuegos: Imágenes fijas, fondos 3D, fondos hechos a base de tiles, fondos con diferentes planos de Scholl, entre otras. En este proyecto se han usado las técnicas de mapa de tiles y la generación procedural. Mapa de tiles Los mapas creados a partir de tiles tienen su origen en la necesidad de almacenar una gran cantidad de mapas sin que repercuta negativamente en el peso del juego. Las tiles son pequeñas piezas de mapa de un tamaño generalmente fijo que se almacenan una única vez en un tile set y pueden ser usadas tantas veces como haga falta para formar mapas más complejos, los cuales se definen generalmente como una matriz de enteros, cada uno de los cuales es el identificador de la tile a usar, el cual sirve para encontrar dicha tile dentro del tile set. Por ejemplo: Tile set A la izquierda vemos el mapa como una matriz y a la derecha al ser dibujado. 37 Acceder a la tile correspondiente en el tile set en función de su identificador es sencillo. Suponiendo un tamaño de tile tamañoTile X tamañoTile, y un tile set con tilesAncho tiles de ancho, accedemos a la posición origen de la tile a partir de la cual se va a dibujar con la siguiente fórmula: tileX = (tileID % tilesAncho) * tamañoTile tileY = (tileID / tilesAncho) * tamañoTile Animación El mapa no se encuentra fijo, sino que se desplaza para simular el movimiento a través del mismo. Normalmente la porción de mapa que se dibuja depende de la cámara, que a su vez suele depender de la posición del jugador. En el caso de los shoot ‘em up, sin embargo, la cámara no suele estar fija sobre el jugador sino que se desplaza de forma automática y constante. Así, a cada instante actualizamos la posición del mapa en función de la cámara, y dibujamos el trozo de mapa que se va a mostrar en pantalla, evitando así el coste innecesario de dibujar lo que queda fuera de cámara. Escoger qué trozo de mapa en función de la cámara es sencillo, suponiendo un tamaño de tiles de tamañoTile X tamañoTile, dibujaríamos tantas tiles como cupiesen en pantalla (anchoPantalla / tamañoTile, altoPantalla / tamañoTile) a partir de la posición de la matriz de tiles camaraX % tamañoTile, camaraY % tamañoTile. Lectura de un fondo de fichero Los mapas usados han sido almacenados en un fichero de texto y parseados al ser leídos y usados por el juego. El formato es simple, la primera línea del fichero mapa contiene dos enteros con el ancho y alto del mapa en tiles, y a partir de la siguiente línea se encuentra la matriz de identificadores de tile que definen dicho mapa. Fondo procedural La generación procedural 19 hace referencia a la generación de contenido, en este caso el fondo, no de forma manual sino mediante algoritmos. Otra forma de explicar la generación procedural es como “aleatoriedad controlada”. Dicha técnica se ha aplicado a la creación de un fondo para el juego, creando un cielo a partir de diferentes nubes. Dichas nubes pueden moverse a diferentes velocidades dependiendo de su altura, simulando así su mayor o menor distancia respecto a la cámara. Además, las nubes más cercanas (y por tanto las que se dibujan más grandes y a mayor velocidad) se dibujan los objetos del juego y de forma transparente sobre estos, de forma que solo se aplique el efecto de transparencia, simulando entrar en la nube, a los elementos del juego y no al fondo. Así, a cada tipo de nube se le ha asignado una probabilidad y un tiempo aleatorio entre nubes, de forma que aunque se vayan creando de forma aleatoria en tiempo de ejecución las cantidades y posiciones se mueven dentro de unos parámetros que hacen que el fondo 19 https://en.wikipedia.org/wiki/Procedural_generation 38 siempre luzca correctamente, sin escasez ni exceso de nubes, ni estas apareciendo siguiendo patrones no deseados. Además, se han usado ambas técnicas conjuntamente para formar mapas con mayor detalle. En concreto, usando la técnica del mapa de tiles se ha creado el fondo de un bosque y por encima de este se generan proceduralmente las nubes. 39 Niveles Para probar la funcionalidad implementada, se han creado dos niveles (sin contar los niveles de los jefes), uno generado proceduralmente y otro creado a mano. Como se ha mencionado en el apartado anterior, en este proyecto en concreto no existe interacción entre los elementos del juego, como puedan serlo el propio jugador o los enemigos, y el escenario, y por tanto se han almacenado por separado, permitiendo además cualquier combinación de ambos. Así pues, en este proyecto un nivel se define exclusivamente por la serie de enemigos que lo forman, y van apareciendo secuencialmente en pantalla. Nivel procedural El primer nivel se encarga de crear proceduralmente los obstáculos que forman dicho nivel. Concretamente, filas o columnas de enemigos o balas de diferentes colores se escogen aleatoriamente con un intervalo de tiempo regular entre ellas y aparecen de cualquier extremo de la pantalla. La ventaja de crear niveles generados proceduralmente es la rapidez con la que, a base de unas pocas reglas, se pueden crear un número infinito de niveles de longitud infinita. Sin embargo, existe el riesgo de que el nivel resulte soso y no cree niveles interesantes, para lo cual no suele bastar con unas pocas reglas sino que se debe profundizar y entender correctamente qué patrones puedan dar lugar a niveles interesantes y como mezclarlos, así como controlar la curva de dificultad. Nivel creado a mano El segundo nivel de prueba se ha creado a mano. Para facilitar su creación y modificación y debido a la limitación de tiempo, en vez de leerse el nivel de un fichero y a pesar de que existe dicha funcionalidad, el nivel está creado dentro del propio código. La desventaja es el tiempo que requiere crear un nivel así, además de que el esfuerzo invertido resulta en un nivel finito, además de la dificultad que a veces puede acarrear realizar modificaciones sobre el mismo, al tener que reestructurar todo el nivel. Sin embargo, al tener control total de los elementos que forman el nivel y como se desarrolla este, es más fácil controlar y crear tramos interesantes, evitar la repetición y gestionar la curva de dificultad. 40 Subsistema de audio El proyecto requiere de una forma de gestionar los efectos de sonido y pistas de audio, así como contar con diferentes formas de controlar su reproducción y aplicar efectos. Dicha funcionalidad ha sido encapsulada en un manager de audio. XNA ofrece dos alternativas para implementar el apartado sonoro de un juego: XACT(Cross-platform Audio Creation Tool): Se trata de un engine de sonido que ofrece una serie de funcionalidades ya implementadas, como efectos, crear colas de sonidos y asignarles prioridad a cada elemento de la misma, comprimir pistas, etc que pueden ser utilizados desde una aplicación independiente al código. También cuenta con una api, incluida en Xna.Framework.Audio, con una serie de clases y funciones que permiten realizar acciones básicas como reproducir sonido, pausarlo o cambiar el nivel de volumen. Es esta alternativa la que se utilizará en el desarrollo de este proyecto. Este framework consta de una clase básica, SoundEffect, para almacenar una pista de audio .wav, que únicamente puede ser reproducida usando el método de clase Play(); SoundEffect soundEffect; soundEffect = Content.Load<SoundEffect>(@"Audio/fichero"); soundEffect.Play(); Para tener control de la reproducción esa pista debe ser instanciada en una variable de tipo SoundEffectInstance, que además de reproducir la pista de audio permite pausar, parar, reanudar, "loopear" y controlar el nivel de volumen durante la reproducción de la misma. Para instanciar y reproducir usamos el método CreateInstance() de la clase SoundEffect. SoundEffectInstance instance; instance = Content.Load<SoundEffect>(@"Audio/fichero").CreateInstance(); instance.Play(); La principal ventaja en cuanto a funcionalidad de SoundEffect respecto a SoundEffectInstance es que esta última no permite reproducir su sonido varias veces de forma paralela. Pongamos de ejemplo el sonido al disparar una metralleta. Usando un único sonido de disparo, y si se dispara una rafaga SoundEffect nos permitiría reproducir el sonido tantas veces como disparos, pero al usar SoundEffectInstance se debería crear tantas instancias como disparos, lo cual resulta innecesario. Añadir que XNA también cuenta, en Xna.Framework.Media, con las clases Song y la clase MediaPlayer, usadas para almacenar pistas de audio en .mp3 y para reproducirlas, respectivamente. Song song; 41 song = Content.Load<Song>(@"Audio/prueba"); MediaPlayer.Play(song); La principal desventaja es que solo puede reproducirse únicamente una pista de audio al mismo tiempo (normalmente se reserva su uso para reproducir música de fondo), limitación que no existe en las clases SoundEffect y SoundEffectInstance. En el proyecto se usarán únicamente estas dos últimas, debido a la libertad de de reproducir diferentes pistas de audio de fondo al mismo tiempo (por ej, música de fondo y lluvia). El subsistema de audio implementado se encarga de todo lo relacionado con el audio del juego y se compone de las siguientes clases: AudioManager La clase principal encargada de gestionar y manejar el resto de clases, así que como de ofrecer una serie de métodos de control de las diferentes pistas de audio. Funciona como una caja negra que puede ser usada por los demás objetos del juego, los cuales le indican que acción quieren reproducir en un sonido en concreto de los almacenados por el manager. Para permitir esto se ha realizado la siguiente implementación: Debido a la pequeña cantidad de sonidos que requiere el juego, en vez de cargarlos y liberarlos según sea necesario se dejan cargados desde el inicio. Así, la clase AudioManager cuenta con un vector para sonidos de tipo SoundEffect y uno para los sonidos de tipo SoundEffectInstance: El vector usado para almacenar los SoundEffect es únicamente del tipo soundData, que contiene el SoundEffect y variables para el control de su cadencia, en los que se profundizará más adelante. Para controlar la reproducción de los mismos se cuenta únicamente con un método: ● playSound(id, vol, pan): Reproduce el sonido id (coincide con su posición en el vector de SoundEffects) con un volumen (relativo al volumen global) indicado por vol y un panorama indicado por pan. Vol es un valor entre 0 y 1000 que se normaliza al intervalo 0..1 que maneja unity, y panorama un valor entre -1 y 1 que indica la posición del sonido. Por ejemplo, 0 hace que suene centrado (mismo volumen por ambos altavoces en estéreo), mientras que -1 hace que únicamente suene por el izquierdo. El vector para almacenar los sonidos de tipo SoundEffectInstance es ligeramente más complejo y requiere de una estructura auxiliar debido a la posibilidad de contar con más opciones para su reproducción y a la necesidad de guardar cierta información relativa al estado y control de cada instancia. Dicha estructura se ha llamado instanceData, en la cual almacenamos: 48 la CPU cuando este sea necesario, no usando un tiempo que queda libre para otros menesteres como puede ser la incursión de más objetos o en tiempo de GPU, entre otros, o simplemente liberarlo para reducir el consumo. Acople de RT-DESK y XNA Este proyecto usa RT-DESK en forma de DLLs, las cuales se incluyen en el proyecto permitiendo acceder a toda la funcionalidad de RT-DESK. De la creación de estas DLLs se encargó David Pérez Climent en su proyecto “creación de un videojuego en XNA usando RT-DESK”, en cuya memoria describió el proceso, el cual a continuación se resume brevemente. Adaptación C# y C++ Originariamente RT-DESK se proporcionaba en forma de una biblioteca escrita en C++ compilada a código máquina. XNA, sin embargo, únicamente trabaja usando el lenguaje C#, el cual compila a código intermedio CIL(Common Intermediate Language 20 ), ejecutado por la CLR (Common Language Runtime 21 ), impidiendo que librerías de C++ sean llamandas directamente desde C#. C# permite llamar a funciones de bibliotecas nativas mediante el servicio PInvoke, pero no así la creación y utilización de clases nativas, lo cual es un requisito pues RT-DESK necesita crear clases que hereden de RTDESK_CEntity y sobrescriban el método ReceiveMessage, el cual es llamado directamente desde el código nativo. La solución a este problema pasó por usar el lenguaje C++/CLI para crear una clase puente. Así, se crearon diferentes clases C++/CLI, una por cada una de las clases de RT-DESK que se necesitaban utilizar (RTDeskEngine, RTDeskEntity y RTDESK_CMsg). Adaptación de la clase Game RT-DESK sustituye al núcleo de un videojuego, el bucle principal. El segundo problema que surgió fue que el bucle que provee la clase Game de XNA, oculto al diseñador, y que además de encargarse de actualizar y dibujar los elementos del juego también se encarga de otras como la gestión de la ventana de juego o la comunicación con los dispositivos gráficos de salida. De esta forma, para permitir que el control de bucle principal pasase a RT-DESK se creó una nueva clase Game que se encargase de esas tareas que hasta ahora realizaba XNA en su bucle principal: Se creó un proveedor de servicios, implementando la interfaz IServiceProviery, y el servicio GraphicsDeviceService, implementando IGraphicsDeviceService, que proporciona el dispositivo gráfico. Se gestionó la creación de la ventana de juego, mediante la clase form de System.Windows.Forms. 20 https://en.wikipedia.org/wiki/Common_Intermediate_Language 21 https://msdn.microsoft.com/es-es/library/8bs2ecf4%28v=vs.110%29.aspx 49 Aparte de los mencionados anteriormente, la adaptación de RT-DESK a XNA ha presentado otros problemas. El origen de estos es el mismo, no usar el bucle principal que ofrece XNA y que se encargaba de algunas tareas esenciales: Problemas con la entrada, la cual no funciona correctamente debido a que el bucle principal de XNA no está ahí para asegurarse que la entrada se actualiza a la misma velocidad que el juego, que es algo que no se permite realizar desde fuera. Se ha intentado ejecutar el bucle de XNA en paralelo al de RT-DESK para asegurar esa actualización periódica de los periféricos de entrada, tanto usando hilos como ejecutando el bucle de rt-desk desde dentro del bucle de xna pero no se llegó a una solución. Una solución segura pasaría por usar otras librerías ajenas a XNA para gestionar la entrada. Problemas de audio. En particular, con el tipo “sound” (Ver la sección de audio) que permite reproducir sonidos sin controlarlos. Si no está el bucle de XNA funcionando, se lanza una excepción avisando explícitamente de esto mismo y terminando la ejecución. Una solución pasaría por usar únicamente SoundInstances o, de nuevo, usar una librería ajena a XNA como puede ser FMOD, enfocada a la reproducción de audio. Pruebas Entorno de pruebas Un computador formado por procesador Intel Xeon CPU E5-2620 2GHz, 16 GB RAM, tarjeta gráfica NVIDIA GeForce GTX 760, con Windows 7 Professional 64 bits como sistema operativo, usando service pack 1, Microsoft Visual Studio C# Express 2010 y XNA 4.0. Diseño de las pruebas En cada una de las versiones del juego (Continua y discreta, usando RT-DESK), se han realizado dos tests distintos, uno con enemigos “normales” y otra con jefes (Estos disparan balas). En ambos casos estaban activados los fondos por tiles y el personaje principal (sin entrada). La ejecución de todos los elementos es determinista (No se han usado elementos procedurales, ni aleatorios ni entrada del jugador). En cada test se varia la cantidad de enemigos (De 1000 en 1000 en el caso de la prueba con enemigos normales y de 100 en 100 en el de los jefes), y por cada cantidad se han realizado cinco pruebas distintas para un mayor rigor en la medida y comparación. Cada una de estas pruebas dura 30 segundos y se contabiliza qué fracción se destina a cada una de las siguientes fases:  Fase de dibujado (Draw), en la que se dibujan los objetos.  Fase de actualización (Update), en la que se actualizan los objetos.  Fase de idle, tiempo restante no usado. 50 Resultados En ambos tests los resultados han sido muy similares, variando únicamente la magnitud (El jefe es más pesado computacionalmente que el enemigo normal, además de disparar, y por tanto hacen falta menos para saturar el sistema). Los siguientes datos pertenecen a la prueba con jefes. En primer lugar, los resultados de la versión continua: Se puede observar que el sistema se satura con casi 600 objetos creados, que es cuando la fase de update y de draw suman un tiempo total superior al tiempo de iteración, y por tanto el tiempo de idle es 0. Al saturarse obviamente el tiempo de update y de draw deja de crecer, aunque en cada iteración si es mayor, propiciando una caída de frames (ralentización de la ejecución). 51 En la versión con RT-DESK se puede observar en la gráfica superior como el tiempo de actualización y dibujado es menor que en la versión continua, resultando en un mayor tiempo de idle y por lo tanto requiere de mayor carga para saturarse (Unos 700 elementos). En la inferior se muestran los frames por segundo, los cuales empiezan a caer al alcanzar el estado de saturación, de nuevo necesitando para ello más carga que en la versión continua. La diferencia entre una versión y otra sería la posibilidad de contar con unos 100 jefes extra en la versión de RT-DESK (o unos 2000~ enemigos normales, según la prueba con enemigos), aunque dicho tiempo extra podría ser usado para cualquier tarea. 52 Conclusiones El uso de RT-DESK ha sido más sencillo y rápido de lo esperado, además de haber quedado patente sus ventajas frente al bucle principal tradicional. Por otra parte el desarrollo del videojuego, partiendo de cero y realizando todo el diseño, la planificación e implementación ha sido de gran ayuda para entender y permitirme profundizar en una de las aplicaciones de la informática que más interés me despiertan y que apenas se ha tocado en la carrera, la creación de videojuegos. La lección más valiosa que he sacado en esta parte es sobre la importancia de la planificación. Como medio de expresión, es difícil saber desde el principio cómo va a ser el videojuego que se va a hacer porque siempre hay cosas que depurar o cambiar, cosas que sobre la marcha se descubren, o algunas que simplemente se van a quitar. Sin embargo, como proyecto y como programa que es, gran parte del mismo sí se puede (Y debería) de planificar. La prueba de esto es que por muchas semanas que dediqué a hacer pruebas pensando acerca del diseño del juego, buscando algo que fuese una base sólida, a la hora de implementarlo cambié cosas. Y además, en el momento en que empecé a planificarlo, a marcarme metas objetivas a distintos plazos, desarrollarlo se hizo más sencillo, y teniendo control de esos aspectos que si se pueden planificar puede uno fácilmente realizar cambios, si fuesen necesarios, en esos otros aspectos más “artísticos”. En cuanto a la planificación temporal y del esfuerzo que asumí me llevaría, en general he tardado lo que asumí o un poco menos, en parte porque varias de la tareas se simplificaban al haber realizado algunas previas (Por ejemplo, el primer Boss costó más que los siguientes, que se beneficiaron de su código). Una de mis preocupaciones al empezar el proyecto fue el coste de hacer la adaptación a RT-DESK. Sin embargo, y como he comentado antes, resulto sencillo y directo. La tabla y el diagrama de Gantt actualizados se encuentran en la siguiente página. Relación del trabajo con estudios cursados La realización del proyecto ha resultado beneficiosa de cara a poner a prueba lo aprendido en la carrera, y especialmente en mi especialidad de ingeniería del software. Se ha aplicado muy especialmente cuestiones referentes a la programación, gráficos por computador y técnicas de diseño y gestión de proyectos, estas últimas se han revelado muy útiles como se ha comentado en el proyecto anterior. La ingeniería informática es muy amplia y en la carrera se han tocado muchas ramas. No las pondré en prácticas todas, y no todas me gustan, pero entré en la universidad buscando poder hacer juegos, y he aprendido lo suficiente como para poder hacerlo. Y destacar especialmente la destreza general como ingeniero obtenida a lo largo de la carrera, que me han permitido coger una tecnología completamente desconocida para mi como es RTDESK y comprenderla y aplicarla de forma sencilla, así como aplicar lo estudiado a algo que no se ha estudiado explícitamente, como son los videojuegos. Un compañero suele decir que en la universidad lo más importante que se aprende es a aprender, una base sobre la que construir el resto de conocimientos, con lo que estoy muy de acuerdo. 53 Se ha pintado en rosa el tiempo real sobre el tiempo estimado, pintado en azul. 54 Trabajos futuros La tecnología RT-DESK está validada por diferentes proyectos, el siguiente paso debería de ser pulirla y facilitar su uso a un mayor número de desarrolladores. Sin embargo, los problemas anteriormente descritos (adaptar el bucle principal, manejar la ventana, problemas de input, limitaciones en el audio) que hacen que para usar RT-DESK junto con XNA haya que renunciar a muchas de las posibilidades de esta (En parte por funcionar como una caja negra) y sustituirlas por otras opciones me hacen pensar en si no sería más adecuado adaptar RTDESK a otra tecnología que sí permita una acople perfecto entre ellos. De querer continuar por esta linea, sería recomendable centrarse en MonoGame una vez esté completa, la adaptación libre de XNA, y ver si se tiene acceso al código del bucle principal y se puede realizar esa mejor integración. Aparte de las versiones ya existentes que hacen uso de OpenGL, otro buen candidato y con las ventajas de XNA sería SFML, al usar C++ y no proveer de un bucle principal cerrado la adaptación sería trivial, pero si el proyecto de adaptar RT-DESK al motor Unity saliera adelante esta sería la opción ideal, tanto por ser uno de los más usados como por contar con una tienda desde la cual se podría distribuir (incluso vender) RT-DESK a una gran cantidad de usuarios, pertenecientes además de una comunidad conocida por su gran cantidad de documentación y recursos, lo cual sin duda sería de ayuda para retroalimentar la difusión y comprensión de RTDESK. 55 Agradecimientos Me gustaría agradecer la posibilidad que me ha dado Ramón Mollá, director del proyecto, de hacer como proyecto final de carrera lo que he querido hacer desde que empecé esta, un videojuego, así como por toda la ayuda y consejos durante el desarrollo del mismo. También, además, a todos los compañeros que han trabajado en los diferentes proyectos de RT-DESK, especialmente a David Pérez, cuya adaptación de XNA a RT-DESK y documentación de la misma han sido imprescindibles para este proyecto. Y para acabar a mis padres, por “aguantarme en casa”, poniéndome las cosas, otra vez, bastante más fáciles. 56 Glosario Bucle principal: Núcleo del juego encargado de gestionar la entrada y actualizar y dibujar los elementos que lo forman. GDD: Game Design Document (Documento de diseño del videojuego). Se trata de un documento que describe los diferentes aspectos del videojuego y que sirve como guía de referencia para todo el equipo. HUD: Heads up display, la interfaz gráfica que se muestra durante el juego para mostrar el valor de diferentes atributos de la partida como energía del personaje, vidas, tiempo, etc RT-DESK: Real Time Discrete Simulation Kernel, es una librería diseñada para la gestión temporal de eventos discretos en tiempo real. Shoot ‘em up: Género de videojuegos donde prima la acción, habilidad con el mando y los reflejos. Sprite: Asset gráfico 2d usado para representar visualmente los elementos del juego. Sprite sheet / Sprite set: Imagen donde se guardan los diferentes sprites que forman las animaciones de los elementos de un juego. XNA: Conjunto de herramientas creadas por Microsoft para facilitar y apoyar la creación de videojuegos. 57 Fuentes https://en.wikipedia.org/wiki/Video_game http://rtdesk.blogs.upv.es http://www.statista.com/topics/868/video-games http://entropyinteractive.com/2011/02/game-engine-design-the-game-loop/ Bibliografía: Jesse Schell, Art of game design: a book of lenses. Aaron Reed, Learning XNA 4.0. David Pérez Climent, Creación de un videojuego en XNA usando RT-DESK. Pablo de la Ossa Pérez, Zentract: Engine con simulación discreta para videojuegos 2D. 64 Bala explosiva Se muestra como un pequeño punto fijo que sirve de aviso, ya que momentos después le sigue una explosión en esa misma posición. Únicamente es de color rojo. Láser El láser parte de la nave enemiga hasta el borde de la pantalla. Puede ser de color azul, verde o rojo, además de poder alternar entre ambos siguiendo diferentes patrones. Onda Similar al láser pero en vez de ser lineal tiene forma circular y se expande desde su origen (el enemigo que la dispara). Puede ser de color azul, verde o rojo, además de poder alternar entre ambos siguiendo diferentes patrones. 65 Tipos de enemigos Enemigos En el diseño de los enemigos normales (no con los jefes) no sigue un patrón concreto sino que se van a crear enemigos básicos cuyo comportamiento se pueda modificar fácilmente para crear un gran número de enemigos diferentes, asignando diferentes patrones de movimientos y de disparos, así como atributos (como energía, nº de puntos). Por ejemplo, un enemigo que aparezca por la un lado de la pantalla y avance disparando hacia el otro. Un enemigo que aparezca por un lado de la pantalla, dispare y vuelva por donde ha venido. Enemigos que puedan aparecer espontáneamente en el interior de la pantalla, o de forma a la posición del protagonista. También enemigos que dispares siguiendo diferentes patrones de tipo, color, dirección y demás atributos. Jefe 1 Este jefe permanece en la parte central superior de la pantalla sin moverse mientras dispara rachas de balas rojas en todas direcciones. La velocidad de las balas oscila entre un mínimo y una máximo. Tras acabar con ⅔ de su vida ralentiza las balas por debajo del mínimo y empieza a añadir más balas, y cuando está a punto de morir a aumentar su velocidad y añadir también balas grises. 66 Jefe 2 Este jefe se desplaza por la pantalla siguiendo un recorrido fijo y soltando ondas de cualquiera de los tres colores de forma aleatoria. Poco a poco el intervalo entre ondas se va estrechando y las ondas son más rápidas. Llegado cierto punto, las ondas se limitan a los colores azul y rojo. Además, una onda puede ser de diferentes colores (porque está dividida a trozos o porque se va alternando). Jefe 3 Este jefe se mueve por la pantalla rebotando en sus esquinas. Cuenta con un escudo que lo envuelve protegiéndolo de disparos y que no puede ser destruido, pero que tiene una abertura por la que poder dispararle. El escudo gira, la dirección del giro cambia de tanto en tanto. Desde el escudo salen disparadas bolas rebotantes, y cuanto más cerca se está de vencer al jefe, más balas hay en pantalla. Además, de vez en cuando se lanzan balas destructibles en todas direcciones. 67 Jefe 4 Este jefe se encuentra en el centro de la pantalla, no se mueve por ella pero rota constantemente. Dispara lasers continuos que rotan junto a él. Conforme se le va quitando vida, la velocidad de gira aumenta, así como el número de lasers y sus patrones, además de añadir algunos disparos extra. 68 Escenarios A parte de un simple color de fondo, muy práctico para evitar distracciones visuales, el juego cuenta con otros dos tipos de escenarios, los basados en mapas de tiles y los generados proceduralmente. Mapa de tiles Son escenarios creados a mano a partir de un conjunto de tiles. Se aplica un scroll para que de sensación de avance y se crea un loop para que resulte infinito mientras dure la fase. Usando esta técnica se creará el escenario del bosque. Mapa procedural Aunque un mapa procedural puede ser un mapa de tiles, en este caso la técnica se usará para crear un escenario basado en el cielo donde se creen sobre la marcha diferentes elementos de diferentes tipos (por ejemplo, nubes) y velocidades (para simular profundidad) siguiendo unas reglas y restricciones. En el caso de las nubes además se aplicará un shader o alguna técnica de forma que se impriman de forma semitransparente sobre los otros elementos (protagonista, enemigos, balas, etc.) pero no sobre el propio fondo (de forma que se mantengan blancas).