1 Gracias a mi tutor Miguel Angel por guiarme y aconsejarme a lo largo de la realización de este trabajo. Gracias a mis compañeros de clase por hacer que el camino hasta aquí haya sido mucho más divertido, en especial a Aitor y Fran que me han acompañado a diario en las clases del Master. Y por último, gracias a mis amigos y familiares, en especial a mi madre, mi padre y mi hermana por acompañarme en el día a día. 1 “Lo que puedas hacer hoy, no lo dejes para mañana” Mi abuela 3 Índice de contenidos Índice de figuras ....................................................................................................................................9 Índice de tablas ...................................................................................................................................11 1. 2. 3. Introducción ................................................................................................................................13 1.1. ¿Qué es un videojuego basado en el procesamiento de imágenes? .................................13 1.2. Historia de los videojuegos basados en el procesamiento de imágenes ...........................13 1.3. Actualidad de los videojuegos basados en el procesamiento de imágenes ......................16 1.4. Motivación .........................................................................................................................17 1.5. Objetivos ............................................................................................................................18 1.6. Estructura del documento .................................................................................................18 Análisis ........................................................................................................................................21 2.1. Metodología .......................................................................................................................21 2.2. Herramientas......................................................................................................................21 2.2.1. Software .....................................................................................................................21 2.2.2. Hardware ...................................................................................................................22 2.3. Ámbito ................................................................................................................................23 2.4. Negocio ..............................................................................................................................24 2.5. Futuro .................................................................................................................................24 Diseño .........................................................................................................................................27 3.1. Argumento .........................................................................................................................27 3.1.1. 3.2. Título del videojuego .................................................................................................27 Mecánica ............................................................................................................................27 3.2.1. Flujo de la partida ......................................................................................................27 3.2.2. Jugabilidad .................................................................................................................28 3.3. Arquitectura .......................................................................................................................28 3.3.1. Unity...........................................................................................................................28 3.3.2. Videojuego ........................................................................................................................29 3.4. Captura de fotografías .......................................................................................................29 5 3.5. Contenido ...........................................................................................................................29 3.5.1. Escenario ...........................................................................................................................30 3.5.2. Armas ................................................................................................................................32 3.5.3. Enemigos ...........................................................................................................................33 3.5.4. Objetos recolectables .......................................................................................................33 3.5.6. Otros elementos del escenario .........................................................................................34 3.5.7. HUD ...................................................................................................................................34 4. 5. 3.6. Progreso .............................................................................................................................39 3.7. Requisitos ...........................................................................................................................39 3.7.1. Requisitos funcionales ...............................................................................................39 3.7.2. Requisitos no funcionales ..........................................................................................43 Desarrollo....................................................................................................................................45 4.1. Captura de fotografías .......................................................................................................46 4.2. Escenario ............................................................................................................................47 4.2.1. Generación de blobs ..................................................................................................47 4.2.2. Generación del contenido del escenario ...................................................................50 4.3. Lógica del jugador ..............................................................................................................54 4.4. Armas .................................................................................................................................54 4.5. Enemigos ............................................................................................................................55 4.6. HUD ....................................................................................................................................55 Conclusiones ...............................................................................................................................57 5.1. 5.1.1. Captura de imágenes desde dentro del videojuego ..................................................57 5.1.2. Procesamiento de la imagen capturada para generar el escenario del videojuego ..57 5.1.3. Contenido de los escenarios ......................................................................................58 5.1.4. Manejo del jugador ....................................................................................................58 5.1.5. Aspecto visual y sonoro .............................................................................................59 5.1.6. Testear el videojuego.................................................................................................59 5.2. 6 Repaso de objetivos ...........................................................................................................57 Imágenes del resultado ......................................................................................................59 5.3. Desarrollo futuro ................................................................................................................62 5.4. Reflexión general................................................................................................................63 6. Bibliografía ..................................................................................................................................65 7. Anexo ..........................................................................................................................................67 7.1. Split and merge ..................................................................................................................67 7.1.1. Split ............................................................................................................................67 7.1.2. Merge.........................................................................................................................68 7.2. Flood fill ..............................................................................................................................69 7 Índice de figuras Figura 1.1: Game Boy Camera (1998) .................................................................................................14 Figura 1.2 : Eye Toy (2003) ..................................................................................................................14 Figura 1.3: Kinect (2010) .....................................................................................................................15 Figura 1.4: Spirit Camera (2012) .........................................................................................................15 Figura 1.5: Pixel Press (2013) ..............................................................................................................16 Figura 1.6: HoloLens y Minecraft (2015).............................................................................................16 Figura 1.7: Pokemon Go (2016) ..........................................................................................................17 Figura 2.1: Nuclear Thorne (2015) ......................................................................................................23 Figura 3.1: Flujo de la partida .............................................................................................................28 Figura 3.2: Fotografía sin procesar .....................................................................................................31 Figura 3.3: Fotografía Procesada ........................................................................................................31 Figura 3.4: Mockup del menu principal ..............................................................................................35 Figura 3.5: Mockup del menu de aspectos .........................................................................................36 Figura 3.6: Mockup de la interfaz de toma de fotografía ...................................................................37 Figura 3.7: Mockup la interfaz de la partida .......................................................................................38 Figura 3.8: Mockup del menú de pausa ..............................................................................................38 Figura 4.1: Diagrama de clases general ..............................................................................................45 Figura 4.2: Jerarquía del escenario .....................................................................................................46 Figura 4.3: Recorte de la fotografía ....................................................................................................47 Figura 4.4: Fotografía normalizada .....................................................................................................48 Figura 4.5: Fotografía reducida ...........................................................................................................48 Figura 4.6: Ejemplo de puntos de un Edge Collider 2D ......................................................................51 Figura 4.7: Bordes de los blobs ...........................................................................................................51 Figura 5.1: Menu principal ..................................................................................................................60 Figura 5.2: Tomando una fotografía ...................................................................................................60 Figura 5.3: Fotografía procesada ........................................................................................................61 Figura 5.4: Jugando una partida 1.......................................................................................................61 Figura 5.5: Jugando una partida 2.......................................................................................................62 Figura 5.6: Jugando una partida 3.......................................................................................................62 Figura 7.1: Split and Merge - Imagen original .....................................................................................68 Figura 7.2: Split and Merge - Split .......................................................................................................68 Figura 7.3: Split and Merge - Merge ...................................................................................................69 Figura 7.4: Variantes del algoritmo Flood fill ......................................................................................70 Figura 7.5: Proceso del algoritmo Flood fill ........................................................................................71 9 10 Índice de tablas Tabla 3.1: Probabilidad de aparición de los elementos ......................................................................32 Tabla 3.2: Características del ataque del jugador ...............................................................................32 Tabla 3.3: Atributos principales de los enemigos ...............................................................................33 Tabla 3.4: Efectos adicionales de las gemas .......................................................................................34 Tabla 3.5: Requisito funcional 1 - Activar o desactivar el sonido .......................................................39 Tabla 3.6: Requisito funcional 2 - Reproducir audio ...........................................................................40 Tabla 3.7: Requisito funcional 3 - Salir del videojuego .......................................................................40 Tabla 3.8: Requisito funcional 4 - Tomar una fotografía ....................................................................40 Tabla 3.9: Requisito funcional 5 - Dividir por zonas la fotografía .......................................................40 Tabla 3.10: Requisito funcional 6 - Generar la malla de colisión ........................................................40 Tabla 3.11: Requisito funcional 7 - Generar accesos entre zonas ......................................................40 Tabla 3.12: Requisito funcional 8 - Posicionar enemigos ...................................................................41 Tabla 3.13: Requisito funcional 9 - Posicionar obstáculos ..................................................................41 Tabla 3.14: Requisito funcional 10 - Posicionar objetos .....................................................................41 Tabla 3.15: Requisito funcional 11 - Pausar el videojuego .................................................................41 Tabla 3.16: Requisito funcional 12 - Gestionar el HUD .......................................................................41 Tabla 3.17: Requisito funcional 13 - Mover al protagonista ...............................................................42 Tabla 3.18: Requisito funcional 14 - Desactivar los elementos lejanos ..............................................42 Tabla 3.19: Requisito funcional 15 - Interactuar con los objetos del escenario .................................42 Tabla 3.20: Requisito funcional 16 - Disparar .....................................................................................42 Tabla 3.21: Requisito funcional 17 - Aplicar un power up ..................................................................42 Tabla 3.22: Requisito funcional 18 - Interacción de los enemigos con el entorno .............................43 Tabla 3.23: Requisito funcional 19 - Resolver impactos de las balas..................................................43 Tabla 3.24: Requisito funcional 20 - Finalizar partida .........................................................................43 Tabla 3.25: Requisito no funcional 1 - Rendimiento ...........................................................................43 Tabla 3.26: Requisito no funcional 2 - Usabilidad...............................................................................43 Tabla 3.27: Requisito no funcional 3 - Fiabilidad ................................................................................44 Tabla 3.28: Requisito no funcional 4 - Apariencia ..............................................................................44 Tabla 3.29: Requisito no funcional 5 - Escalabilidad ...........................................................................44 11 1. Introducción 1.1. ¿Qué es un videojuego basado en el procesamiento de imágenes? Lo primero que se debe abordar en este documento es definir que es un videojuego basado en el procesamiento de imágenes. En general se puede describir como un videojuego donde el análisis de una imagen, ya sea en tiempo real mediante un dispositivo de captura o utilizando una imagen capturada con anterioridad, tiene un impacto en el comportamiento del videojuego. Normalmente se suele relacionar más el uso de procesamiento de imágenes en campos como la medicina o en sistemas de vigilancia. Sin embargo en los últimos años, ha aumentado la popularidad dentro de la industria gracias a dispositivos como Kinect de Microsoft o los propios dispositivos de captura de los smartphones y tablets. El tipo de interacción que causa el procesamiento de una imagen en el videojuego puede afectar a diferentes ámbitos del mismo. Puede afectar directamente a la jugabilidad, por ejemplo con el sistema de captura de Kinect, podrías mover al personaje principal haciendo gestos con la mano o incluso imitando el movimiento de trotar. Otro ejemplo es el uso meramente estético, haciendo que un personaje o escenario de un videojuego tenga características de la imagen capturada. Para profundizar más en las posibles aplicaciones del procesamiento de imagenes en los videojuegos, a continuación se va a hacer un repaso histórico desde su origen hasta la actualidad. 1.2. Historia de los videojuegos basados en el procesamiento de imágenes A lo largo de la historia de los videojuegos, la forma de utilizar el procesamiento de imágenes para generar una experiencia de juego ha sido de lo más variada. El procesamiento de imágenes suele requerir un hardware potente, y por lo tanto, sobre todo en los inicios, se limitaba el procesamiento a pequeños elementos de la imagen. Se va a hacer un repaso a distintas tecnologías surgidas en las últimas dos décadas, ya que más o menos es a partir de entonces, cuando el hardware era lo suficiente potente como para soportar este tipo de videojuegos. En el año 1998 fue lanzada Game Boy Camera, un accesorio para todas las Game Boy de Nintendo lanzadas hasta el momento. Este accesorio además de permitir tomar y editar fotos, permitía también añadir elementos de las fotografías tomadas a varios minijuegos. Por ejemplo, podías 13 fotografiar la cara de un amigo y hacer que este fuese un enemigo de un videojuego de naves de scroll vertical. FIGURA 1.1: GAME BOY CAMERA (1998) En 2003, fue lanzada para PlayStation 2, Eye Toy, una cámara digital que permitía mediante visión artificial y reconocimiento de gestos, que el jugador interactuase con el videojuego haciendo movimientos con su cuerpo. Este tipo de dispositivos permitía a los jugadores realizar más actividad física mientras jugaba a los videojuegos, y resultaba ideal para disfrutar junto a los amigos. FIGURA 1.2 : EYE TOY (2003) En el año 2010 apareció para la Xbox 360 de Microsoft el dispositivo Kinect, lo que venía a ser una mejora de lo visto años atrás con el Eye Toy de Sony. Con un reconocimiento de gestos bastante más preciso que el de Eye Toy, permitía una interacción más exacta con los videojuegos. 14 FIGURA 1.3: KINECT (2010) Con el lanzamiento de la Nintendo 3DS, hubo varios videojuegos que aprovecharón su cámara de 3 dimensiones para generar nuevas experiencias de juego. Por ejemplo, el videojuego Spirit Camera, lanzado en el año 2012, aparecían fantasmas y espectros en el entorno que el jugador iba grabando. Este videojuego además, se vendía junto a un libro en el que según la página que estuviese abierta, al enfocarlo con la cámara se desvelaba una parte diferente de la trama del videojuego. FIGURA 1.4: SPIRIT CAMERA (2012) En el año 2013 fue lanzada en Kickstarter la campaña de financiación para Pixel Press, una aplicación para dispositivos móviles que permitía a un usuario crear escenarios para un videojuego de plataformas 2D similar a Super Mario Bros de Nintendo. El usuario podía dibujar sus escenarios a mano en una plantilla cuadriculada, que después era fotografiada y procesada para generar el escenario dentro del videojuego. Se trata de una aplicación muy interesante a nivel educacional, ya que permite a los más pequeños comenzar a diseñar niveles para sus videojuegos sin necesidad de utilizar software más complejo. 15 FIGURA 1.5: PIXEL PRESS (2013) 1.3. Actualidad de los videojuegos basados en el procesamiento de imágenes En la actualidad, se siguen desarrollando nuevas formas de utilizar el procesamiento de imágenes para generar experiencias de juego. Sobre todo está en auge el uso de la realidad aumentada, para representar en tiempo real información virtual junto al mundo real. Uno de los casos más sonados es el de las nuevas HoloLens de Microsoft. Una tecnología que a través de unas gafas genera una realidad mixta con el entorno. Como demostración de esta tecnología, se mostró un escenario del videojuego Minecraft (adquirido por Microsoft en el año 2014) que el jugador era capaz de visualizar sobre un entorno real. Además, el jugador también podía interaccionar con ese escenario haciendo gestos con su cuerpo. FIGURA 1.6: HOLOLENS Y MINECRAFT (2015) Otro proyecto a tener en cuenta en cuanto a realidad aumentada, es Pokemon Go, un videojuego para dispositivos iOS y Android, que representa el mundo de Pokemon sobre el mundo real. Por 16 ejemplo, si el usuario se encuentra navegando en un barco, dentro del videojuego aparecerán Pokemons acuáticos. FIGURA 1.7: POKEMON GO (2016) 1.4. Motivación Como ya se ha visto, el uso el procesamiento de imágenes en los videojuegos puede ser de lo más variopinto. Tanto la característica afectada del videojuego como los dispositivos de captura pueden ser muy variados y las posibilidades son muy amplias. En este caso, el dispositivo de captura va a ser un smartphone o tablet, mediante el uso de la cámara integrada de los mismos. Lo que resulta atractivo de este tipo de dispositivos, es que pueden ser llevados a cualquier lugar cómodamente, y la variedad de imágenes capturadas es muy amplia. En cuanto a la característica afectada del videojuego, en este caso va a ser el escenario donde transcurre la acción. El objetivo es que cada partida ofrezca un desafio diferente a la anterior, y desde luego, dada la gran variedad de imágenes que pueden ser capturadas por una cámara, el videojuego dispondrá de una variedad de escenarios casi infinita. De todo lo repasado en el estado del arte, el videojuego más similar al que se pretende realizar es Pixel Press. Ya a título personal, este va ser mi primer videojuego de tamaño considerable para dispositivos móviles. Dado que ya tengo experiencia en el desarrollo de videojuegos para ordenadores, para este desarrollo quiero utilizar características solo disponibles en dispositivos móviles, en este caso la cámara de los mismos. Pienso que puede dar mucho juego el hecho de poder estar en cualquier lugar, sacar un foto y que en el videojuego se genere una experiencia basada en esa foto. Por supuesto, lo más importante es que esa experiencia sea divertida, y eso es lo que voy a intentar desarrollando este videojuego. 17 1.5. Objetivos Este trabajo de fin de master tiene como objetivos los siguientes: Permitir la captura de imágenes desde dentro del videojuego con una gran variedad de smartphones y tablets diferentes. Procesamiento de la imagen capturada para generar el escenario del videojuego. Añadir contenido al escenario generado (enemigos, objetos, obstáculos, etc.). Implementar el manejo del jugador adaptado a dispositivos de diferentes tamaños. Dotar al videojuego de un aspecto visual y sonoro básico. Probar y corregir lo necesario del videojuego para hacerlo lo más entretenido posible. El grueso de este trabajo se lo van a llevar los 2 primeros puntos, pero los otros 4 también son obligatorios para lograr un videojuego completo. 1.6. Estructura del documento Para aclarar mejor como esta distribuido el contenido de esta memoria, a continuación se hace una breve descripción de los diferentes capítulos: 1. Introducción: Se realiza una descripción del tema a tratar así como un repaso a los antecedentes del mismo. También se aclara la motivación y los objetivos principales del trabajo. 2. Análisis: Se define la metodología de trabajo que va a usarse así como las herramientas software y hardware que se utilizarán para realizar el trabajo. También se lleva a cabo un análisis de requisitos, tanto funcionales como no funcionales. Por último se define el público al que va dirigido este trabajo y que opciones de negocio tendría. 3. Diseño: Se realiza una descripción de los diferentes aspectos del videojuego, como la fase de captura de imagen, las mecánicas jugables, la arquitectura del sistema o el contenido (escenario, enemigos, etc.). A partir de ese diseño también se extraen los requisitos del proyecto. 4. Desarrollo: Se explica como ha sido implementado lo diseñado en el capítulo anterior, haciendo énfasis sobre todo en el procesamiento de la imagen capturada. 5. Conclusiones: Se hace una reflexión sobre como ha ido el desarrollo del trabajo y si se han logrado cumplir los objetivos previstos. También se explica que cosas podrían mejorarse si se quiere continuar con el desarrollo del videojuego. 6. Bibliografía: Se nombran las fuentes de información que han servido de ayuda para la realización del trabajo. 18 7. Anexo: Se explica más en detalle los diferentes algoritmos investigados para el procesamiento de imágenes. 19 2. Análisis 2.1. Metodología Para el desarrollo de este trabajo, se ha optado por utilizar una metodología ágil de desarrollo, ya que al tratarse de un trabajo realizado por un único desarrollador, no merece la pena gastar mucho tiempo en la creación de documentación, más propio de equipos de desarrollo grandes donde es necesario coordinar a los diferentes departamentos. En concreto se ha optado por utilizar la metodología FDD (Feature Driven Development), en español Desarrollo Basado en Funcionalidades. Esta consiste en un primer análisis global del sistema, para posteriormente generar una lista de las diferentes funcionalidades que lo compondrán. A partir de ese momento se van desarrollando de forma iterativa las diferentes funcionalidades hasta completar el sistema. Esta metodología se complementa muy bien con la forma de realizar el TFM, ya que permite ir enseñando al tutor las diferentes funcionalidades de forma independiente. El tutor desde un principio conoce todas las funcionalidades que serán implementadas y podrá guiar al alumno en cada una de ellas aportando el feedback que considere necesario. 2.2. Herramientas 2.2.1. Software Para el desarrollo del videojuego, se ha optado por el uso de herramientas gratuitas. Hoy en día la tendencía va a favor de facilitar el acceso a las herramientas de desarrollo. Motores de videojuegos con Unreal Engine o entornos de desarrollo como Visual Studio, previamente de pago, han sido puestos a disposición de los desarrolladores de forma gratuita. Las herramientas utilizadas son las siguientes: Cocos2d-x: Librería de desarrollo de videojuegos multiplataforma. Permite compilar un mismo código en C++ a dispositivos Android, iOS, etc. Unity 5: Herramienta de desarrollo de videojuegos que incluye un motor de renderizado, un motor físico, un motor de audio, un sistema de scripting, entre otras características que permiten abarcar todos los aspectos que componen a un videojuego. La característica por la cual destaca esta herramienta es la capacidad de compilar el videojuego para muchas plataformas diferentes, aunque en este caso se compilará principalmente para Android e iOS. 21 Unity Remote 4: Se trata de una aplicación para Android e iOS. Permite ejecutar el videojuego desde Unity el videojuego vía cable USB, de modo que no es necesario compilar cada vez que se realizan cambios. Esto permite agilizar bastante el proceso de desarrollo para dispositivos móviles. Visual Studio Community 2015: El entorno de desarrollo por excelencia de Microsoft. Permite editar y depurar el código realizado para el videojuego. El lenguaje de programación utilizado será C#. Paint .net: Programa de edición y creación de imágenes. Permite realizar ediciones rápidas, ya que resulta sencillo de utilizar. Se utilizará tanto para realizar el apartado gráfico del videojuego, como para crear y editar las imágenes que incluye esta memoria. Audacity: Programa de grabación y edición de sonidos. Se utilizará para grabar y modificar los efectos de sonido del videojuego. Microsoft Office: La famosa suite de ofimática de Microsoft. Será utilizada para escribir la propia memoria del TFM y preparar las diapositivas para la presentación. Más adelante se explicará por que se ha incluido en la lista dos herramientas de desarrollo de videojuegos diferentes (Cocos2dx y Unity). 2.2.2. Hardware El hardware utilizado para el desarrollo del videojuego es el siguiente: Ordenador de sobremesa (montado por piezas) Intel Core i7 930 2.80 Ghz 6 Gb de RAM Nvidia GeForce GTX 950 con 2 Gb de RAM Portatil (Lenovo Z580) Intel Core i5 3210M 2.50 Ghz 8 Gb de RAM Nvidia GeForce GT 630M con 2 Gb de RAM Samsung Galaxy S4 Mini 22 Qualcomm MSM8930 Snapdragon 400 dual-core 1.70 Ghz 1.5 Gb de RAM GPU Adreno 305 Resolución de 540 x 960 pixels, 4.3 pulgadas Puntualmente también serán utilizados un iPhone 5s, un iPad 2 y un MacBook, para probar el comportamiento del videojuego en dispositivos de Apple. 2.3. Ámbito Siempre que se desarrolla un videojuego hay que tener en mente el público objetivo del mismo. Esto cobra especial importancia en dispositivos móviles, ya que la cantidad de usuarios y competencia es muy grande. Definir bien el público objetivo permite aumentar las probabilidades de éxito, ya que se pueden centrar los esfuerzos en gustar a ese perfil concreto de usuario. Sin embargo, la naturaleza de este videojuego es más experimentar con el procesamiento de imágenes que crear un producto centrado en agradar a un perfil concreto. Una vez lanzada una primera versión del producto, si que se podría hacer un análisis de que tipo de usuario es el que más suele jugarlo y centrar las futuras actualizaciones para ese perfil. Por lo pronto, una manera básica de definir el público objetivo del videojuego, es definir el género del mismo. En este caso, el género es el de los shoot’em up. En resumen, se trata de videojuegos donde ves lo que ocurre desde una vista aérea, pudiendo mover libremente al protagonista y disparar en múltiples direcciones a los enemigos van apareciendo. Uno de los ejemplos más antiguos de este tipo de videojuegos es el Asteorids (1979) de la mítica Atari. En la actualidad dentro de ese género encontramos videojuegos como Nuclear Throne (2015) desarrollado por Vlambeer. FIGURA 2.1: NUCLEAR THORNE (2015) Otra forma de definir el público objetivo es concretar si el videojuego dirigido a jugadores casual o jugadores hardcore. Explicado de forma sencilla, los jugadores casual son aquellos que juegan una partida de vez en cuando simplemente como pasatiempo. Los jugadores hardcore son aquellos que 23 dedican bastante tiempo al videojuego, motivados por conseguir todos los desafíos que este les propone. En el ámbito de los dispositivos móviles, la gran mayoría de los videojuegos van dirigidos a jugadores casual. Muchos de los jugadores de este tipo juegan cuando tienen que esperar en alguna cola, una parada del metro, etc. En definitiva son videojuegos para matar el tiempo. En este caso el videojuego también va dirigido a un público casual, que por curiosidad saque una foto de algo que les rodea y puedan jugar una partida rápida en un escenario generado a partir de esa foto. Ese factor de curiosidad tambien sirve para acotar más el público objetivo, ya que una persona que le guste experimentar se puede sentir atraida por los tipos de escenarios que se pueden llegar a generar. Por último, otra forma de acotar aún más el público objetivo es por la edad de los jugadores. Normalmente el género de los shoot’em up suele gustar bastante a los adolescentes y jóvenes varones. Aunque dado que es un género ya con bastantes años, puede haber varones más mayores que también se interesen por él. A pesar de que en el videojuego se dispara contra los enemigos, no se hace énfasis en mostrar un contenido violento, por lo que el videojuego sería adecuado incluso para los más pequeños. Resumiendo, el público objetivo de este videojuego es aquel que: Le guste el género de los shoot’em up. Busque jugar partidas rápidas. Sienta curiosidad por que tipos de escenario se pueden generar. Tenga entre 12 y 27 años aproximadamente. 2.4. Negocio En un principio, se va a optar por un modelo de negocio añadiendo publicidad en el menú principal del videojuego. Se trata de un modelo simple y fácil de implementar, aunque no reporta grandes beneficios en videojuegos con pocas descargas. Como recompensa para el jugador fiel, si consigue desbloquear todo el contenido del videojuego, la publicidad será retirada. 2.5. Futuro Al tratrarse de un videojuego con una propuesta diferente a lo que se suele ver en el mercado, resulta interesante añadir recogida de datos para registrar el compotamiento de los jugadores con el videojuego. El motor Unity permite añadir esta característica mediante el servicio Unity Analytics. 24 Analizando la información recogida por el servicio, se puede averiguar mejor por donde encaminar las actualizaciones futuras del videojuego, o un mejor modelo de negocio para el mismo. 25 3. Diseño 3.1. Argumento Un pequeño ser conocido como Pictrotter siente una gran obsesión por las fotografías. Pasa los días observando y paseando por las propias fotografías. Sin embargo, desde hace un tiempo unos parásitos amenazan las integridad de las fotografías y eso es algo que Pictrotter no puede permitir. Pictrotter se enfrentará a todos aquellos peligros que acechen a sus preciadas fotografías, con el fin de preservarlas y admirarlas con tranquilidad. 3.1.1. Título del videojuego El videojuego tiene como nombre Pictrotter, en referencia a como es conocido el protagonista del mismo. A la hora de decidirlo también se ha tenido encuenta como podría posicionarse bien en las tiendas de aplicaciones como Google Play. Un nombre corto y descriptivo del contenido favorece que los usuarios sepan lo que estan descargando. En este caso “Pic” hace referencia a “Picture” que significa fotografía, y “Trotter” significa trotador. La traducción al castellano es algo como “trotador de las fotografías”. 3.2. Mecánica En este apartado se explica el flujo que tiene una partida y la forma que tiene el jugador de interactuar con el videojuego. 3.2.1. Flujo de la partida Como la mayoría de los videojuegos, al iniciarlo se muestra un menú principal desde donde el jugador puede iniciar la partida. Lo primero que se hace es tomar una fotografía con la cámara del dispositivo. Ésta es procesada dividiéndola por zonas, y el jugador puede volver a tomar otra fotografía y empezar a jugar. Una vez el jugador ha empezado a jugar, tiene que explorar el nivel generado enfrentándose a los enemigos y desbloqueando las diferentes zonas. Cuando el jugador llega a la salida del nivel, se vuelve a mostrar el menú principal. 27 FIGURA 3.1: FLUJO DE LA PARTIDA 3.2.2. Jugabilidad Cuando el jugador empieza a jugar el nivel generado, puede realizar las siguientes acciones: Moverse: puede desplazarse en cualquier dirección (360 grados). Disparar: puede disparar en cualquier dirección (360 grados). Se ha tratado de mantener una jugabilidad simple dadas las limitaciones de un dispositivo táctil dentro del género de los shoot’em up. 3.3. Arquitectura Para este apartado, conviene realizar primero un repaso de la arquitectura que sigue el motor Unity 5 y posteriormente analizar como es la arquitectura propia del videojuego, ya más enfocada en las necesidades concretas del mismo. 3.3.1. Unity Esta parte se va a tratar de una forma resumida, ya que Unity es una herramienta muy completa. Se hace referencia solo las partes relacionadas con como se organizan los elementos del videojuego. Unity 5 sigue una arquitectura basada en componentes, donde todos los elementos del videojuego consisten en GameObjects. Cada GameObject posee siempre el componente de transformación, que determina su posición, rotación y escala. Sin embargo, lo interesante es que a cada GameObject se le puede añadir más componentes, por ejemplo un renderizador de sprites en 2D, propiedades físicas, un script que define su comportamiento, etc. Otra característica importante es la posibilidad de organizar los GameObjects de forma jerárquica en la propia interfaz del motor. Esto ayuda por ejemplo a que la posición de un GameObject dependa de la de su padre, o que si desactivas al padre también se desactiven sus hijos. Este tipo de funcionalidades son muy utilizadas a la hora de desarrollar un videojuego. Unity además permite la creación de escenas, que no es más que un conjunto de GameObjects organizados al gusto del desarrollador. Un videojuego puede tener solo una escena abierta en cada 28 momento. Ejemplos típicos de escenas pueden ser la escena del menu principal, o la escena de la partida. Por último, destacar la posibilidad de crear Prefabs que ofrece el motor, que no son mas que GameObjects pre diseñados. Se asemejan a las clases de un lenguaje orientado a objetos, donde después se pueden crear diferentes instancias de la misma. Esto ofrece mucha versatilidad a la hora de crear contenido para el videojuego, combinando componentes de diferentes maneras. Por ejemplo, para GameObject con un componente de tipo “Enemigo”, que contiene las características de los enemigos, se puede crear el Prefab del “Enemigo tipo 1”, del “Enemigo tipo 2”, etc... simplemente alterando los valores de ese componente. 3.3.2. Videojuego Al tratarse de un videojuego donde el escenario del mismo es diferente en cada partida, es muy importante tener bien organizado el contenido del mismo, de forma que sea fácil acceder los diferentes elementos a la hora de generar el contenido de una partida. Para ello el uso de Prefabs resulta esencial. Estas son organizadas dentro de un gestor de recursos, al cual se puede acceder en el momento de generar un escenario de una forma sencilla. 3.4. Captura de fotografías Esta es la parte más peculiar del videojuego, ya que la mayor parte del resto de videojuegos no requiere la captura de fotografías dentro del mismo. A la hora de tomar la fotografía, se le permite seleccionar las cámaras disponibles de su dispositivo móvil, independientemente del modelo. Normalmente suele haber una cámara trasera y otra frontal. Dado que en el mercado existen dispositivos con muchas cámaras diferentes y con resoluciones de pantalla también diferentes, se opta por recortar la fotografía de modo que sea cuadrada en lugar de rectangular. Esta es una forma efectiva de lidiar con toda esa variedad a la que se ha hecho referencia antes. Además, también se debe permitir al jugador poder repetir la captura de fotografía en el caso de que no le convezca la que ha tomado. 3.5. Contenido El contenido hace referencia a todo aquello que aparece en el videojuego cuando se ha iniciado una partida. 29 3.5.1. Escenario Dar forma al escenario es la parte más difícil del desarrollo del videojuego. Dado que el escenario se forma a partir de la imágen que ha capturado el jugador, las variantes que pueden aparecer son muy amplias. Una característica que se encuentra presente en todas las fotografías, son los colores. Tomando esto como punto de partida a la hora de generar el escenario, se asegura que para toda fotografía hay un escenario resultante. La división de la imagen por colores suele conocerse como “segmentación de imagen por color”, para lo cual existen diferentes algoritmos que sirven para ese propósito. Teniendo en cuenta las necesidades concretas del videojuego, es necesario estudiar e identificar cual de esos algoritmos es el que mejor se adapta al mismo. El escenario del videojuego tiene como elemento de fondo la propia fotografía tomada, pero dado que todas son cuadradas, resulta necesario hacer algo para añadir variedad. Los colores de la fotografía son aprovechados para dividir por zonas el escenario. A pesar de que el problema de relación de aspecto de las fotografías tomadas por distintos dispositivos se soluciona recortándola, también se debe de normalizar la resolución de la misma. Esto es necesario para que de una fotografía de mayor resolución no se genere un escenario de mayor tamaño que en una de menor resolución. A la hora de dividir por zonas, es necesario analizar el color de cada pixel e ir formando blobs con los píxeles similares adyacentes. Un blob no es más que un conjunto de píxeles que comparten alguna característica. Resulta necesario también limitar el tamaño mínimo de los blobs, para que no se generen escenarios con demasiadas zonas, ya que se pretende que las partidas no lleven mucho tiempo finalizarlas. A continuación se muestra un ejemplo división por zonas de una fotografía: 30 FIGURA 3.2: FOTOGRAFÍA SIN PROCESAR FIGURA 3.3: FOTOGRAFÍA PROCESADA Como se puede observar en las figuras anteriores, para formar cada zona se escogen los colores similares de los píxeles adyacentes. Una vez estan formadas las zonas, es necesario definir una forma de transición entre ellas. Para ello se utilizan unos teletransportadores, que al situarse encima de ellos se accede a la siguiente zona. No se puede volver a una zona anterior, por lo que el jugador tiene que explorar bien una zona antes de abandonarla. 31 Además, para cada zona hay que definir cual es su borde, tanto para delimitarlo visualmente, como para crear una pared física y que el jugador no pueda salir de ella a no ser que encuentre el teletransportador. Cuando se llega a esta fase de la generación del escenario, solo queda rellenar las zonas con diferentes elementos: enemigos, objetos, obstáculos, etc... Este relleno se realiza de forma aleatoria, teniendo cada uno de los elementos una pequeña probabilidad de aparecer. En la siguiente tabla se refleja la probabilidad de aparecer de cada tipo de elemento: Elemento del escenario Probabilidad de aparecer Obstáculo 10 % Enemigo 2% Gema 1% TABLA 3.1: PROBABILIDAD DE APARICIÓN DE LOS ELEMENTOS En alguno de los apartados posteriores se define más en profundidad los elementos que pueden aparecer en los escenarios. 3.5.2. Armas El jugador utiliza siempre el mismo tipo de arma, unos cañones situados en las palmas de su mano. A pesar de no disponer de más armas, el jugador si que puede encontrar por el escenario modificadores que afectan a algunas de las características del arma: Velocidad de disparo Tamaño del proyectil Velocidad del proyectil En la siguiente tabla se representan los valores por defecto de cada característica, y los valores mejorados: Característica Por defecto Con mejora Velocidad de 0,5 seg. 0,3 seg. disparo Tamaño del 25 cm. 50 cm. proyectil Velocidad del 6 m/s 10 m/s proyectil TABLA 3.2: CARACTERÍSTICAS DEL ATAQUE DEL JUGADOR 32 3.5.3. Enemigos Existen 3 tipos de enemigos a los que el jugador tiene que enfrentarse. Su inteligencia artificial es básica, ya que no se trata del objetivo principal del trabajo. A continuación se describe cada enemigo en detalle. Reboteador Se trata de un enemigo que rebota por el escenario, sin pararse en ningún momento. Si colisiona con el jugador, le hace daño al mismo. Por lo tanto es un enemigo que hay que procurar no tener cerca en ningún momento. Torreta Se trata de un enemigo estático, que dispara al jugador en caso de entrar en su rango de detección. Reboteador con disparo Tiene el mismo comportamiento que el reboteador, pero además dispara al jugador en caso de entrar en su rango de detección. Enemigo Salud Daño Velocidad de movimiento Velocidad de ataque (tiempo entre ataques) Reboteador 75 15 6 m/s - Torreta 100 10 - 2 seg. Reboteador con disparo 50 10 4 m/s 2 seg. TABLA 3.3: ATRIBUTOS PRINCIPALES DE LOS ENEMIGOS 3.5.4. Objetos recolectables En el videojuego solo existe un tipo de objeto que el jugador puede recoger, las gemas. Las gemas, aparte de servir de moneda de cambio para poder adquirir nuevos aspectos para el personaje, también tienen otros efectos adicionales: Curación: Todas las gemas recuperan 20 puntos de salud al jugador. Efecto adicional: Existen ciertos tipos de gema con colores diferentes que además de curar, le proporcionan cierta mejora durante el resto de la partida. Un mismo efecto adicional no es acumulable. Las gemas sin efectos adicionales son de color morado. En la siguiente tabla se recogen los efectos adicionales que pueden tener las gemas: Color de la gema Descripción de la mejora Azul Reduce el daño recibido en un 25 % 33 Verde Aumenta la velocidad del jugador en un 25 % Naranja Aumenta la velocidad de disparo del jugador Roja Aumenta el tamaño de los proyectiles del jugador Amarilla Aumenta la velocidad de los proyectiles del jugador TABLA 3.4: EFECTOS ADICIONALES DE LAS GEMAS 3.5.6. Otros elementos del escenario Existen otros elementos que aparecen en los escenarios generados y són igualmente importantes: Obstáculos: Se añaden con el fin de que el escenario no se encuentre muy vacío y requiera cierto desafio moverse por él. Para evitar que los obstáculos puedan obstruir pasillos, se permite destruirlos disparándoles. Teletránsportadores: Permiten al jugador acceder a la siguiente zona, simplemente situándose encima de ellos. Una vez ha sido utilizado, el jugador ya no puede volver a la zona anterior. 3.5.7. HUD Una parte importante para que el jugador se mantenga informado durante la partida, es diseñar una buena interfaz de usuario (HUD). El videojuego contiene 5 tipos de HUD diferentes que se explican a continuación. Menú principal Consta de las siguientes secciones: 34 Título del videojuego: Muestra el título, Pictrotter. Gemas: Muestra el número de gemas disponibles. Comenzar: Botón para comenzar la partida. Aspectos: Botón para mostrar el menú de aspectos. Sonido: Botón para activar o desactivar el sonido del videojuego. Salir: Botón para salir del videojuego. FIGURA 3.4: MOCKUP DEL MENU PRINCIPAL Menú de aspectos Consta de las siguientes secciones: Título del menú: Muestra el título, aspectos. Cuadrados de selección: En cada cuadro hay una imagen del aspecto. El cuadro que tiene el borde rojo es el seleccionado actualmente. Los aspectos no desbloqueados tienen encima de su cuadro el precio en gemas. Volver: Botón para regresar al menú principal. 35 FIGURA 3.5: MOCKUP DEL MENU DE ASPECTOS Interfaz de toma de fotografía Consta de las siguientes secciones: Foto: Recuadro donde se muestra la imagen captada por la cámara del dispositivo. Cambiar: Botón para cambiar entre las cámaras del dispositivo. Por ejemplo, la trasera o la frontal. Tomar: Botón para capturar una fotografía. Volver: Botón para volver al menú principal. Jugar: Botón para comenzar una partida, sólo en el caso de que se haya tomado una fotografía. 36 FIGURA 3.6: MOCKUP DE LA INTERFAZ DE TOMA DE FOTOGRAFÍA Interfaz de la partida Consta de las siguientes secciones: Barra de vida: Representa la vida que le queda al protagonista. Se reduce en tamaño conforme se va perdiendo vida. Pausa: Botón para detener la partida y acceder al menú de pausa. Gemas: Texto donde se muestra la cantidad de gemas recogidas por el jugador. Stick de movimiento: Stick para mover al personaje por el escenario. Stick de ataque: Stick para dirigir los ataques del personaje. 37 FIGURA 3.7: MOCKUP LA INTERFAZ DE LA PARTIDA Menú de pausa Consta de las siguientes secciones: Título: Muestra el texto de pausa. Reanudar: Botón para continuar con la partida. Salir al menú: Botón para terminar la partida y regresar al menú principal. FIGURA 3.8: MOCKUP DEL MENÚ DE PAUSA 38 3.6. Progreso La progresión que se lleva a cabo en el videojuego sucede sólo a nivel estético, ya que el argumento es simplemente anecdótico y a nivel jugable no existe progresión entre los niveles más allá de la forma y cantidad de zonas de los mismos. En cada partida que juega el jugador, puede recoger las gemas que aparecen distribuidas por el escenario, que más tarde pueden utilizarse para comprar nuevos aspectos para el personaje principal. Además, cuando el jugador accede a una nueva zona del escenario, ya no puede regresar a la anterior, lo que provoca que el videojuego sea más lineal. 3.7. Requisitos Una vez realizado el diseño del videojuego, se puede definir un conjunto de requisitos que tienen que ser cumplidos para completar su desarrollo. En los siguientes apartados se definen los requisitos funcionales y no funcionales del proyecto. 3.7.1. Requisitos funcionales Los requisitos funcionales hacen referencia a las diferentes funcionalidades que el sistema tiene que ser capaz de llevar a cabo. Dada la cantidad de funcionalidades que puede contener un videojuego, se especifican los requisitos funcionales de una forma más general. Distinguiremos entre 2 niveles de importancia: Esencial: El sistema debe cumplir ese requisito a toda costa, ya que sin él faltaría una parte importante del mismo o directamente no podría funcionar. Deseable: Es recomendable que el sistema cumpla ese requisito, pero siempre podría seguir funcionando sin él. A continuación se muestran los requisitos funcionales que tiene que cumplir el sistema. El orden de los mismos es más o menos el orden con el que aparecen dentro del sistema. Primero se muestran funcionalidades del menu principal, después de generación de una partida y por último referentes al manejo del jugador durante una partida y como interacciona el entorno con él. Título Activar o desactivar el sonido Importancia Deseable Descripción El videojuego tiene que permitir activar o desactivar el sonido del mismo. Esto cobra especial importancia en disposivos móviles, donde la multitarea está muy presente. TABLA 3.5: REQUISITO FUNCIONAL 1 - ACTIVAR O DESACTIVAR EL SONIDO 39 Título Reproducir audio Importancia Deseable Descripción El videojuego tiene que ser capaz reproducir la música de fondo y los efectos sonoros. TABLA 3.6: REQUISITO FUNCIONAL 2 - REPRODUCIR AUDIO Título Salir del videojuego Importancia Esencial Descripción El videojuego tiene que ser capaz de finalizar sus tareas y liberar los recursos correctamente cuando el jugador quiera salir de él. TABLA 3.7: REQUISITO FUNCIONAL 3 - SALIR DEL VIDEOJUEGO Título Tomar una fotografía Importancia Esencial Descripción El videojuego tiene que permitir al usuario tomar una fotografía con alguna de las cámaras del dispositivo móvil. TABLA 3.8: REQUISITO FUNCIONAL 4 - TOMAR UNA FOTOGRAFÍA Título Dividir por zonas la fotografía Importancia Esencial Descripción El videojuego debe procesar la fotografía capturada dividiéndola por zonas. TABLA 3.9: REQUISITO FUNCIONAL 5 - DIVIDIR POR ZONAS LA FOTOGRAFÍA Título Generar la malla de colisión Importancia Esencial Descripción El videojuego debe generar la malla de colisión de rodea a cada una de las zonas. TABLA 3.10: REQUISITO FUNCIONAL 6 - GENERAR LA MALLA DE COLISIÓN Título Generar accesos entre zonas Importancia Esencial Descripción El videojuego debe generar los puntos de acceso entre las diferentes zonas, para que el jugador pueda desplazarse entre ellas. TABLA 3.11: REQUISITO FUNCIONAL 7 - GENERAR ACCESOS ENTRE ZONAS 40 Título Posicionar enemigos Importancia Esencial Descripción El videojuego debe posicionar de forma equilibrada a los enemigos por las diferentes zonas. TABLA 3.12: REQUISITO FUNCIONAL 8 - POSICIONAR ENEMIGOS Título Posicionar obstáculos Importancia Esencial Descripción El videojuego debe posicionar obstáculos de forma equilibrada por las diferentes zonas. TABLA 3.13: REQUISITO FUNCIONAL 9 - POSICIONAR OBSTÁCULOS Título Posicionar objetos Importancia Esencial Descripción El videojuego debe posicionar objetos recolectables por el jugador de una forma equilibrada entre todas las zonas. TABLA 3.14: REQUISITO FUNCIONAL 10 - POSICIONAR OBJETOS Título Pausar el videojuego Importancia Deseable Descripción El videojuego tiene que permitir al jugador pausar el videojuego durante una partida, de modo que la lógica del videojuego se paralice hasta que se decida reanudar la partida o volver al menú principal. TABLA 3.15: REQUISITO FUNCIONAL 11 - PAUSAR EL VIDEOJUEGO Título Gestionar el HUD Importancia Esencial Descripción El videojuego tiene que ser capaz de actualizar la información mostrada en el HUD del jugador (vida, menús, etc..) en función de los eventos que ocurran durante la partida. TABLA 3.16: REQUISITO FUNCIONAL 12 - GESTIONAR EL HUD 41 Título Mover al protagonista Importancia Esencial Descripción El videojuego tiene que permitir al jugador desplazarse por el escenario, con un rango de 360 grados. TABLA 3.17: REQUISITO FUNCIONAL 13 - MOVER AL PROTAGONISTA Título Desactivar los elementos lejanos Importancia Deseable Descripción El videojuego tiene que ser capaz de desactivar lo elementos que se encuentren lejos del jugador en cada momento, de modo que se reduzca la carga de procesos y únicamente reaccionen los elementos cercanos al jugador. TABLA 3.18: REQUISITO FUNCIONAL 14 - DESACTIVAR LOS ELEMENTOS LEJANOS Título Interactuar con los objetos del escenario Importancia Esencial Descripción El videojuego tiene que permitir al jugador recoger los diferentes objetos que puede encontrarse por el escenarios, es este caso las gemas. TABLA 3.19: REQUISITO FUNCIONAL 15 - INTERACTUAR CON LOS OBJETOS DEL ESCENARIO Título Disparar Importancia Esencial Descripción El videojuego tiene que permitir al jugador disparar a su alrededor, con un rango de 360 grados. TABLA 3.20: REQUISITO FUNCIONAL 16 - DISPARAR Título Aplicar un power up Importancia Esencial Descripción El videojuego tiene que ser capaz de aplicar al jugador el efecto de un power up recogido (gemas especiales). TABLA 3.21: REQUISITO FUNCIONAL 17 - APLICAR UN POWER UP Título Interacción de los enemigos con el entorno Importancia Esencial Descripción El videojuego tiene que ser capaz de asignar el comportamiento de los diferentes tipos de enemigos en función de lo que ocurra a su alrededor. 42 TABLA 3.22: REQUISITO FUNCIONAL 18 - INTERACCIÓN DE LOS ENEMIGOS CON EL ENTORNO Título Resolver impactos de las balas Importancia Esencial Descripción El videojuego tiene que ser capaz de identificar los impactos producidos por las balas, ya sean disparadas por el jugador o por los enemigos, y aplicar el efecto correspondiente. TABLA 3.23: REQUISITO FUNCIONAL 19 - RESOLVER IMPACTOS DE LAS BALAS Título Finalizar partida Importancia Esencial Descripción El videojuego tiene que ser capaz de finalizar una partida y volver al menu principal, ya sea porque lo ha decidido el jugador, ha sido derrotado por los enemigos, o ha completado el nivel. TABLA 3.24: REQUISITO FUNCIONAL 20 - FINALIZAR PARTIDA 3.7.2. Requisitos no funcionales Los requisitos no funcionales hacen referencia a aquellas funcionalidades del sistema que no tienen porque ser específicas, sino que se tratan de cualidades más generales que tiene que cumplir el sistema. Distinguiremos entre los mismos niveles de importancia que los requisitos funcionales. A continuación se muestran los requisitos no funcionales más importantes para el tipo de producto que se esta tratando, es decir, un videojuego. Título Rendimiento Importancia Esencial Descripción El videojuego tiene que ir fluido en todo momento a un mínimo de 60 fotogramas por segundo para no afectar a la experiencia de usuario. TABLA 3.25: REQUISITO NO FUNCIONAL 1 - RENDIMIENTO Título Usabilidad Importancia Esencial Descripción Debe de evitarse una excesiva complejidad a la hora de interactuar con el videojuego, sobre todo para los usuarios que juegan por primera vez. TABLA 3.26: REQUISITO NO FUNCIONAL 2 - USABILIDAD 43 Título Fiabilidad Importancia Esencial Descripción Se debe de evitar la aparición de cualquier error que expulse al usuario del videojuego, como bloqueos o cierres inesperados. TABLA 3.27: REQUISITO NO FUNCIONAL 3 - FIABILIDAD Título Apariencia Importancia Deseable Descripción El videojuego debe lucir bien gráficamente para que el usuario no lo rechace a primera vista. TABLA 3.28: REQUISITO NO FUNCIONAL 4 - APARIENCIA Título Escalabilidad Importancia Deseable Descripción La arquitectura del videojuego debe realizarse de forma que sea fácil añadir más contenido al mismo. TABLA 3.29: REQUISITO NO FUNCIONAL 5 - ESCALABILIDAD 44 4. Desarrollo En este capítulo se explica como han sido implementadas las diferentes características que se han diseñado para el videojuego. Se hace énfasis en todo lo relacionado la captura de la fotografía y el procesamiento de la misma, ya que es la parte más importante y compleja del trabajo. Sin embargo, también se explica como han sido implementados otros elementos como la lógica del jugador, los enemigos, etc... aunque con menos detalle. Cabe destacar que el código del videojuego ha sido escrito en inglés, y por lo tanto el nombre de algunos métodos y clases citados posteriormente también lo estarán. Sin embargo toda la explicación sobre su funcionamiento se redacta en castellano, con lo cual no debería ser difícil comprenderlo. Además, para explicar los algoritmos más importantes se muestra un pseudocódigo del mismo. Es posible que no todas las funciones de ese pseudocódigo sean descritas, pero por el propio nombre de las mismas debería entenderse su funcionamiento. Antes de entrar a detallar como ha sido implementada cada una de las características del videojuego, conviene resumir como ha sido organizado el código y los elementos del videojuego, con el fin de tener una visión general del sistema antes de entrar en detalle. La siguiente imagen representa un diagrama de clases general del videojuego: FIGURA 4.1: DIAGRAMA DE CLASES GENERAL HUDManager: Gestiona todo lo referente a la interfaz de usuario, realizando las transiciones entre los diferentes menús del videojuego. 45 GameManager: Gestiona todo lo referente a la generación del escenario y el control de lo que ocurre durante la partida. PhotoManager: Gestiona todo lo referente a la captura de la fotografía y su procesamiento. Player: Gestiona la lógica del jugador. ResourceManager: Se trata de una clase que a través de la cual se obtienen todos los elementos que conforman el escenario. Clases agregadas al ResourceManager: Conforman los diferentes tipos de elementos que pueden agregarse al escenario. En la siguiente imagen se muestra como están organizados los elementos del escenario de forma jerárquica: FIGURA 4.2: JERARQUÍA DEL ESCENARIO Señalar que el videojuego cuenta con una única escena de Unity, a la cual se le activan y desactivan elementos para hacer la transición entre los diferentes menús y estados del videojuego. En los siguientes apartados se explica en detalle como ha sido implementada cada una de las partes del videojuego. 4.1. Captura de fotografías Para esta parte, cabe destacar de que en un principio se planteó la librería Cocos2d-x para el desarrollo del videojuego en lugar de Unity. Sin embargo, trás una investigación inicial, se llegó a la conclusión de que para hacer multiplataforma el videojuego, habría que implementar la captura para cada sistema operativo (iOS, Android), y que ello dejaría poco tiempo para implementar la parte del procesamiento de la imagen. 46 Este problema desaparece con Unity, ya que dispone de un componente llamado WebCamTexture, que actúa como una capa de abstracción para las cámaras de los dispositivos. Sin embargo, sigue habiendo diferencias entre dispositivos Android e iOS en relación a la orientación de la textura. Para solucionarlo ha habido que utilizar código condicional en tiempo de compilación, para que dependiendo de la plataforma de destino, se aplique una rotación o escalado diferente. Por último, para realizar el recorte de la fotografía de modo que tenga una relación de aspecto 1:1 (cuadrada), se ha aplicado la siguiente fórmula sobre los parámetros uv de la textura de la fotografía: uv.anchura = textura.altura / textura.anchura uv.altura = (1.0 – uv.anchura) / 2.0 En la siguiente imagen se puede apreciar el recorte que aplica la fórmula: FIGURA 4.3: RECORTE DE LA FOTOGRAFÍA 4.2. Escenario Esta es la parte más importante del trabajo, que se divide en dos fases principales. La primera fase solo afecta a la imagen capturada, la cual es dividida en blobs (conjuntos de píxeles). La segunda fase utiliza esos blobs para generar el contenido del escenario: físicas, enemigos, objetos, etc... 4.2.1. Generación de blobs Normalización de la textura El primer paso a la hora de generar los blobs es normalizar la fotografía capturada, de modo que tenga la misma resolución independientemente del dispositivo con el que se ha capturado. Se ha tratado de elegir una resolución intermedia, para que las fotos capturadas con dispositivos de poca calidad no se vean muy borrosas al escalarlas. Por supuesto, el escalado también se hace para que la cantidad de píxeles a procesar no sea demasiado alta, ya que al tratarse de dispositivos móviles no se debe exigir mucho procesamiento a la CPU. 47 La resolución elegida trás varias pruebas ha sido de 512 x 512 píxeles, lo que hace un total de 262.144 píxeles a procesar. Esta cantidad aún resulta demasiado alta para dispositivos móviles, por lo que para la generación de los blobs, se extrae una versión simplificada de la textura. Para ello se vuelve a escalar la textura reduciéndola a 64 x 64 píxeles, lo que hace un total de 4.096 píxeles, mucho más asumible. En las siguientes imágenes se puede comparar la fotografía normalizada de 512 x 512 píxeles con la reducida de 64 x 64 píxeles: FIGURA 4.4: FOTOGRAFÍA NORMALIZADA FIGURA 4.5: FOTOGRAFÍA REDUCIDA Se puede apreciar como en la fotografía reducida se siguen distinguiendo bien las formas y los colores, y por lo tanto es suficiente para realizar una división por blobs acertada. Aplicación de filtros Con el fin de facilitar la división por zonas de la fotografía, se aplica un filtro para incrementar el contraste y el brillo de la fotografía. Para ello se aprovecha una clase auxiliar que aplica filtros a las 48 texturas, creada por la comunidad de Unity. Para poder ajustar bien los valores ha habido que esperar a tener terminada la parte de generación de blobs, y los mejores resultados se han obtenido duplicando el brillo y el contraste de la textura. Primera división Para realizar la primera división de la textura en blobs, se ha realizado una investigación de algoritmos ya existentes para ese fin. En el anexo de este documento se puede encontrar información adicional sobre los algoritmos investigados. Se ha optado por utilizar el algoritmo Flood Fill, con las modificaciones necesarias para este caso particular. La elección de este algoritmo se ha hecho principalmente por su sencillez y bajo coste de procesamiento, ya que este proceso en dispositivos móviles no debe de ser demasiado costoso. En el anexo de este documento, se explica el algoritmo Flood Fill en su forma genérica. Dado que para el caso concreto de este videojuego se han tenido que hacer algunas modificaciones, a continuación de explica el funcionamiento del algoritmo ya adaptado: Se añade un primer pixel a una lista de píxeles. Mientras que la lista de píxeles no se encuentre vacía... o Se crea un nuevo blob y se añade a la lista de blobs. o Para el primer pixel de la lista de píxeles... (Función recursiva) Si el píxel no había sido visitado, se añade al último blob de la lista de blobs. Para cada uno de los 4 píxeles vecinos... Si el píxel vecino tiene un color similar al actual, se añade al último blob de la lista de blobs y se vuelve a ejecutar la función recursiva para ese píxel. Si el píxel vecino no tiene un color similar, se añade a la lista de píxeles. o Se elimina el primer píxel de la lista de píxeles. o Si el último blob de la lista de blobs no tiene tiene ningún píxel, se elimina de la lista. Con el procedimiento anterior se obtiene una primera división de la textura, pero es posible que existán blobs demasiado pequeños, incluso que solo tienen 1 píxel. Esto resulta inviable jugablemente, y por lo tanto hace falta realizar un refinamiento de la lista de blobs, para que todos tengan al menos una cantidad mínima de píxeles. 49 Refinamiento Para llevar a cabo el refinamiento, ha sido desarrollado un algoritmo propio. El funcionamiento del algoritmo es el siguiente: Se obtiene la media de píxeles por blob, dividiendo el número total de píxeles entre el número total de blobs. La media resultante es multiplicada por 6. Para cada blob de la lista de blobs... o Si el blob tiene menos píxeles que la media de píxeles por blob... Se comprueba si alguno de los blobs vecinos tiene un color similar. En caso afirmativo, se une el blob actual con el vecino, creando un único blob. Aplicando este sencillo algoritmo, se evita tener blobs demasiado pequeños en el escenario. Con esto la división por blobs de la textura queda completada, y esa textura es mostrada al usuario. El usuario tiene la opción de repetir la fotografía si el resultado no le ha gustado. En caso de que si le guste la división, se da comienzo a la segunda fase de la generación explicada a continuación. 4.2.2. Generación del contenido del escenario Una vez se tiene la lista definitiva de blobs, se puede dar paso a la generación del contenido del escenario. Fondo del escenario El primer paso es situar la fotografía como fondo del escenario, para que el usuario pueda verla mientras juega la partida. Simplemente se crea un sprite de grandes dimensiones, con la textura de la fotografía. La textura utilizada no es la versión simplificada, sino la primera versión después de haber hecho el recorte. Con ello se evita tener un fondo demasiado pixelado y más fiel a la fotografía original. En este punto, ejecuta un bucle que itera por cada uno de los blobs, para generar el contenido de cada uno de ellos. Los siguientes apartados de colisiones, bordes, teletransportes y entidades, son generados para cada blob en cada iteración de este bucle. Colisiones Para crear la colisiones en el borde de cada blob, se ha optado por utilizar el componente EdgeCollider2D de Unity. Este componente crea líneas de colisión entre una serie de puntos definidos en una lista. Esta lista de puntos puede ser de gran tamaño, lo que viene muy bien por la forma irregular que suelen tener los blobs generados. Un ejemplo de lista de puntos podría ser el que se ve en la siguiente imagen: 50 FIGURA 4.6: EJEMPLO DE PUNTOS DE UN EDGE COLLIDER 2D El algoritmo para crear la lista de puntos de cada EdgeCollider2D vuelve a ser de creación propia. Es explicado a continuación en varios pasos: Se crea una lista de puntos (coordenadas xy). Para cada uno de los píxeles del blob... o Se comprueba si hace frontera con otro blob o con el borde de la textura. o En caso afirmativo, se añade ese borde es añadido a la lista de puntos (2 puntos por borde, que forman una línea). En este momento se ha obtenido la lista de puntos que conforman el borde del blob, pero se encuentra desordenada. Cabe tener en cuenta, que el posible que el blob tenga varios bordes diferentes, por ejemplo uno exterior y uno interior, tal y como se aprecia en la siguiente imagen: FIGURA 4.7: BORDES DE LOS BLOBS El siguiente algoritmo se encarga de ordenar la lista de puntos del borde o bordes del blob: Para cada par de puntos de la lista de puntos... 51 o Para cada par de puntos siguientes al par de puntos anterior... Si el primer par de puntos es igual al segundo par de puntos, este segundo par se posiciona a continuación del primero en la lista y se marca como encontrado. o En caso de no haber encontrado un segundo par de puntos quiere decir que se ha completado el primer borde del blob, y se extrae una nueva lista con los puntos restantes. El proceso se sigue ejecutando con esta nueva lista. Una vez se ha ejecutado el algoritmo anterior, ya se dispone de la lista o listas de puntos para cada uno de los bordes el blob. Basta con aplicarselo a cada uno de los componentes EdgeCollider2D y las colisiones con los bordes del blob ya estarán correctamente posicionadas. Bordes Los bordes del blob hace referencia al elemento visible que permite distinguirlos. En Unity existe un componente llamado LineRenderer, que permite definir una lista de puntos sobre la cual se dibuja una serie de sprites. Dado que ya se ha obtenido anteriormente una lista con los puntos que define los bordes del blob al calcular las colisiones, se aprovecha esa lista para definir los puntos del componente LineRenderer. El algoritmo en este caso es muy sencillo: Para cada blob de la lista de blobs... o Se obtiene su componente o componentes EdgeCollider2D. o Para cada uno de esos componentes se recoge la lista de puntos y se aplica al componente LineRenderer. Con esto ya se puede distinguir visiblemente los bordes de cada blob sobre el fondo del escenario. Teletransportes A partir de este paso, se comienza a generar elementos dentro de cada blob. Para evitar que dos elementos se generen en la misma posición, se marca que píxeles del blob están ocupados. El primer elemento que hay que posicionar obligatoriamente son los teletransportes que permiten moverse entre los diferentes blobs. El algoritmo para generar los teletransportes es muy sencillo: Se obtiene el último pixel de la lista de píxeles del blob, se posiciona el teletransportador en sus coordenadas, y se marca el píxel como ocupado. Si el blob actual no es el último de la lista de blobs, se configura el teletransportador con la coordenada del primer pixel del siguiente blob, y se marca como ocupado. 52 Si el blob actual es el último de la lista de blobs, se configura para lanzar el evento de fin de partida. La configuración realizada en los teletransportadores permite durante la partida cambiar la posición del jugador si se sitúa sobre ellos. Entidades Como entidades se entiende el conjunto de obstáculos, enemigos y gemas que pueden aparecer dentro de cada blob. Para la elección del tipo de obstáculo, enemigo o gema, se ha creado un componente ResourceManager, que permite almacenar los Prefabs de todos los tipos de entidades que tiene el videojuego. Este gestor tiene funciones que permiten extraer al azar obstáculos, enemigos o gemas, lo que asegura que exista variedad a la hora de generar las entidades. El algoritmo para generar las entidades es también bastante sencillo: Para cada píxel de la lista de píxeles del blob... o Se comprueba si está ocupado. o En caso negativo, se hace una tirada al azar para posicionar un obstáculo. Esta tirada compara con la probabilidad de aparición de un obstáculo. En caso de fallar, se hace la tirada para posicionar un enemigo. En caso de volver a fallar, se hace la tirada para posicionar una gema. o En caso de que una tirada sea exitosa, se elige al azar un tipo de esa entidad, se posiciona en la coordenada del píxel, y se marca el píxel como ocupado. En el momento que el contenido de todos los blobs de la lista haya sido procesado, ya solo queda un paso más en la generación del escenario. Habilitar / Deshabilitar blobs Unity permite desactivar GameObjects para poder ahorrar procesamiento de la CPU. Dado que el jugador solo puede estar en un blob, resulta ineficiente que el resto de blobs se encuentren activos, dibujandose o ejecutando la lógica de los enemigos. El último paso en la generación del escenario consiste en desactivar todos aquellos blobs donde no se encuentre el jugador (que comienza en el primer blob de la lista). Esto se hace simplemente desactivando el GameObject de cada blob. 53 También es necesario ocultar los píxeles del fondo del escenario que no formen parte del blob donde se encuentra el jugador. Para ello en un principio se modifica el canal alfa de todos los píxeles para que sean transparentes, y solo se dejan opacos los del blob actual. Para el momento en el que el jugador cambia de blob, se deja preparada una función que desactiva el blob anterior y oculta sus píxeles, e inmediatamente después activa el blob nuevo y muestra sus píxeles. Además, se utiliza un efecto de transición (desvanecimiento) para que este cambio brusco no sea apreciado por el jugador. 4.3. Lógica del jugador El jugador consiste en un GameObject de Unity, que se compone de sprites para darle aspecto y un componente Rigidbody2D, para que colisione con el mundo físico. Además se compone de 2 scripts que permiten definir el comportamiento del jugador: Player: Se trata del script más general del jugador. Por un lado se encarga de recoger los valores del stick de movimiento, permitiendo el desplazamiento del jugador en un ángulo de 360 grados. Por otro lado, también se encarga de recoger los valores del stick de ataque, permitiendo tambien disparar en un ángulo de 360 grados. Durante el disparo, también se controla la posición de las manos, ya que el jugador puede estar disparando en una dirección pero moviéndose en la contraria, y por lo tanto las manos siempre tienen que apuntar en la dirección hacia la que se dispara. Health: Este script, además de servir para controlar la salud del jugador, se ha hecho aparte para poder reutilizarlo con los enemigos, e incluso con los obstáculos, ya que estos últimos son destructibles. Contiene eventos para saber cuando la salud ha sido afectada. Por ejemplo, en el caso del jugador, para actualizar la barra de vida del HUD. 4.4. Armas Cabe destacar que tanto el jugador como los enemigos que disparan, siempre tienen el mismo tipo de arma. Se trata de un arma automática que dispara balas a una velocidad concreta. Dado que en este videojuego puede ocurrir que aparcercan muchas balas a la vez en la pantalla, se ha tenido que utilizar un patrón de diseño específico para evitar que la memoria se fragmente. En un videojuego, la tasa de frames por segundo siempre debe de ser constante, y la fragmentación de la memoria puede provocar que el recolector de basura tenga que pasar más de la cuenta, provocando un bajón de frames. El patrón utilizado para crear las balas se llama Object Pool (piscina de objetos), y consiste en instanciar al comienzo de la partida todas las balas que van a ser utilizadas, y desactivarlas. En el 54 momento en el que se dispara una bala se escoge la primera bala disponible de la piscina y se activa. Cuando la bala colisiona y tiene que ser destruida, simplemente se desactiva. Esto evita que se tenga que estar instanciando y destruyendo balas todo el rato, lo que acabaría provocando una gran fragmentación de la memoría y que el recolector de basura pasase más de la cuenta. Esta estatregia es utilizada tanto para las balas del jugador como para las balas de los enemigos. La forma de diferenciar ambas, es una variable booleana, que permite saber si hay que hacer daño al jugador o al enemigo. 4.5. Enemigos Para el desarrollo de los enemigos se ha querido simplificar, en la medida de los posible, el proceso. Para ello viene muy bien la arquitectura basada en componentes de Unity. En lugar de hacer un script diferente para cada tipo de enemigo, lo que se ha hecho es crear scripts de comportamientos. Estos comportamientos son los siguientes: Movimiento de rebote: Hace que el enemigo se mueva continuamente rebotando contra todo lo que colisiona. Además, si entra en contacto con el jugador, le causa daño. Ataque de torreta: Hace que cuando el jugador entra dentro de un rango concreto, el enemigo le dispare balas cada cierto tiempo. Utilizando estos comportamientos, se ha podido crear los enemigos previamente diseñados: Reboteador: Se le ha añadido el script de movimiento de rebote. Torreta: Se le ha añadido el script de ataque de torreta. Reboteador con disparo: Se le ha añadido tanto el script de movimiento de rebote, como el de ataque de torreta. Además, a todos los enemigos se le añade el script “Health”, ya explicado en la lógica del jugador. 4.6. HUD La implementación de la interfaz de usuario, tanto en el menú como durante la partida, ha sido bastante fácil de implementar gracias al sistema que utiliza Unity a partir de la versión 4.6. Este sistema permite editar de forma gráfica los elementos de la interfaz, y además esos elementos se redimensionan con las diferentes resoluciones de los dispositivos móviles. Para actualizar la información del interfaz de usuario, y también para ejecutar los eventos que ocurren en él, se ha utilizado un script controlador llamado “HUDManager”. 55 Para la creación del videojuego, en lugar de crear una escena para el menú, otra para la partida, etc... se ha optado por hacer uso de una única escena. Esto implica que los elementos de la interfaz de usuario tienen que cambiar según en que fase se encuentra el videojuego. El script antes mencionado se encarga de activar y desactivar los elementos de la interfaz, pero además se ha implementado un efecto de desvanecimiento, para que la transición resulte aún más fluida. En cuanto a la actualización de valores del interfaz, como por ejemplo la vida del jugador o la cantidad de gemas recogidas, se ha utilizado el patrón delegado de C#. Este patrón permite mantener el código desacoplado, y solo se actualizan los valores si “HUDManager” registra esos eventos. 56 5. Conclusiones En este capítulo se hace un repaso a como ha ido el desarrollo del trabajo, tanto de sus objetivos concretos como de una manera más general. 5.1. Repaso de objetivos A continuación se repasan uno a uno los objetivos especificados en el capítulo 1 (apartado 5), explicando si han sido cumplidos y que problemas han surgido en el proceso. 5.1.1. Captura de imágenes desde dentro del videojuego Como ya se ha comentado con anterioridad, la idea inicial era desarrollar el videojuego utilizando la librería Cocos2d-x. Dado que ello implicaba tener que programar la captura de la fotografía de forma nativa para cada uno de los sistemas operativos, se decidió utilizar el motor Unity, que proporciona una capa de abstracción para ello. Aun así, con el motor Unity también había que modificar la orientación de la imagen capturada por la cámara, ya que para cada sistema operativo era diferente. Un contratiempo que surgió con esto es que en un principio las pruebas se realizarón para la orientación portrait del dispositivo (en vertical), pero por temas de jugabilidad se decidió cambiar más adelante a la orientación landscape (en horinzontal). Este cambió provocó que el código encargado de gestionar la orientación de la imagen capturada quedase inservible y hubo que volver a hacerlo. Otra parte que llevó más de lo que en un principio se pensaba es el recorte de la textura de la fotografía capturada. Hubo que investigar a fondo el escalado y la forma de gestionar las coordenadas uv que tiene Unity. En definitiva, si se hubiese optado desde un principio por Unity y se hubiese definido desde un principio la orientación del dispositivo, se habría ahorrado un tiempo valioso, pero aún así el objetivo ha sido cumplido. 5.1.2. Procesamiento de la imagen capturada para generar el escenario del videojuego Para este objetivo primero se realizó una investigación de diferentes algoritmos para el procesamiento de imágenes. Ante la grán cantidad de alternativas, se acotó la búsqueda centrándose en aquellos que no requerían un consumo de recursos demasiado alto. Las primeras pruebas se realizaron utilizando el algoritmo Split and Merge, explicado con más detalle en el anexo de este documento. Sin embargo, a pesar de que si se hacía una división de la imagen 57 por regiones, esta división creaba fronteras demasiado rectangulares y poco orgánicas. Esto se debió quizás a que no se supieron ajustar bien los parámetros del algoritmo, o no se aplicacaron las modificaciones necesarias. Además, una vez dividida por zonas la fotografía, resultaba difícil utilizar esa información para organizarlas bien, porque a lo mejor dos zonas adyacentes de la fotografía resulta que estaban en los ramas diferentes del árbol generado. Por los problemas anteriormente citados se decidió cambiar el algoritmo por el Flood Fill, más simple y que dejaba las regiones de la fotografía organizadas en blobs más manejables. El coste a pagar fue una mayor consumo de memoria, pero para compensarlo se reducía el tamaño de la textura procesada. En definitiva, se perdió algo de tiempo con el cambio de algoritmo de procesamiento de imagen, pero mereció la pena, ya que el tener las zonas organizadas por blobs permitió que los objetivos posteriores fuesen más sencillos de realizar. El objetivo ha sido cumplido. 5.1.3. Contenido de los escenarios Una parte que tuvo bastante dificultad fue la creación de las colisiones de cada blob. En primer lugar se tardó en dar con el algoritmo correcto para ordenar la lista de puntos de bordes del blob. Además, luego surgió el problema de los blobs con varios bordes, que en un principio se creaba una lista de puntos que no llegaba a cerrarse. A esto se le sumaba la dificultad añadida de tener que estar tomando fotografías a partir de las cuales se generasen blobs con varios bordes. Fue un proceso de prueba y error bastante tedioso, pero al final se logró identificar bien cual era el problema y solucionarlo. Para el resto de pasos en la generación de contenido no hubo demasiados problemas. Para marcar el borde de los blobs se reutilizó parte de la información ya calculada para crear las colisiones, lo cual ahorró tiempo. Para el posicionamiento de los teletransportadores y las entidades se optó por una opción sencilla basada en el azar, pero suficiente. En definitiva, este objetivo también ha sido cumplido sin muchos problemas, mas allá de las dificultades con la generación de colisiones. 5.1.4. Manejo del jugador En un primer momento, se creó un prototipo de manejo del jugador apoyando el dedo en la dirección contraria hacia donde quería desplazarse. Esta manera resultaba bastante incómoda, sobre todo para desplazarse hacia abajo. Se descartó rápidamente. 58 En su lugar se optó por el uso de 2 sticks, uno para el movimiento y otro para el ataque. Unity dispone de unos controles de este tipo, con lo cual sólo fue necesario adaptarlos a las necesidades del videojuego. En un principio había algún problema con el uso de 2 sticks simultáneos, ya que uno de ellos quedaba inservible. Hubo que realizar alguna modificación en el script de Unity para que acabase funcionando correctamente. A parte de este contratiempo, el resto fue sencillo, ya que en proyectos anteriores ya se había realizado un comportamiento similar del jugador. Por lo tanto el objetivo ha sido cumplido sin muchas dificultades. 5.1.5. Aspecto visual y sonoro Para este objetivo se ha mantenido un aspecto y sonido de prototipo, utilizando figuras geométricas simples para la mayoría de elementos, y unos pocos sonidos grabados y modificados con la herramienta Audacity. Este objetivo si podría haberse mejorado, pero dado que no era la parte principal del trabajo, se dejo para el final y tuvo que hacerse de forma simple. 5.1.6. Testear el videojuego La mayor parte del testeo del videojuego ha ido dirigido probar la generación de escenarios con diferentes tipos de fotografías, ya que es la parte más importante de este trabajo. Para la jugabilidad no se ha dedicado tanto tiempo, pero dado que no se ha arriesgado mucho en este apartado, manteniendola bastante simple, no ha sido necesario dedicar un tiempo excesivo. Donde sí se ha echado en falta dedicar más tiempo, es en jugar muchas partidas completas con diferentes tipos de escenarios, para comprobar si resultan divertidos o por el contrario hay alguno que es demasiado largo y tedioso. 5.2. Imágenes del resultado En esta sección se muestran algunas imágenes con el resultado final del trabajo: 59 FIGURA 5.1: MENU PRINCIPAL FIGURA 5.2: TOMANDO UNA FOTOGRAFÍA 60 FIGURA 5.3: FOTOGRAFÍA PROCESADA FIGURA 5.4: JUGANDO UNA PARTIDA 1 61 FIGURA 5.5: JUGANDO UNA PARTIDA 2 FIGURA 5.6: JUGANDO UNA PARTIDA 3 5.3. Desarrollo futuro Como ya se puede deducir del repaso de objetivos hecho con anterioridad, el primer paso a la hora de seguir con el desarrollo de este trabajo es acabar con los objetivos que han quedado sin cumplir. El videojuego presenta un aspecto visual y sonoro típico de un prototipo, y quedaría bastante trabajo hasta lograr satisfacer esos apartados. 62 Por otro lado, se requiere un mayor testeo en cuanto a los diferentes tipos de escenarios generados, ya que algunos pueden resultar demasiado largos, y habría que limitar la cantidad de zonas por escenario. 5.4. Reflexión general Para finalizar la memoria, voy compartir diferentes impresiones que me he ido llevando a lo largo del desarrollo del trabajo. Este ha sido mi primer proyecto de cierta envergadura para dispositivos móviles, y me ha servido para lidiar con elementos solo presentes en ellos. Por ejemplo, la gran cantidad de resoluciones existentes, las diferencias entre Android e iOS, mantener pequeño el espacio en disco requerido por el videojuego, etc... Al haber optado por una jugabilidad bastante simple, he tenido bastante tiempo para profundizar y depurar bien el procesamiento de la imagen capturada y la generación del escenario, que era la parte principal de este proyecto. Por último, con este trabajo he reforzado aún más mis conocimientos del lenguaje de programación C# y del uso del motor Unity. 63 6. Bibliografía En este capítulo se muestran los links a las principales fuentes de información consultadas para la realización de este trabajo. [1] Microsoft, referencia sobre el lenguaje de programación C#. https://msdn.microsoft.com/eses/library/kx37x362.aspx [2] Unity, scripting API. http://docs.unity3d.com/es/current/ScriptReference/index.html [3] Wikipedia, Game Boy Camera. https://es.wikipedia.org/wiki/Game_Boy_Camera [4] Wikipedia. Eye Toy. https://es.wikipedia.org/wiki/EyeToy [5] Wikipedia. Kinect. https://es.wikipedia.org/wiki/Kinect [6] Wikipedia. Spirit Camera. https://es.wikipedia.org/wiki/Spirit_Camera:_La_memoria_maldita [7] Kickstarter. Pixel Press. https://www.kickstarter.com/projects/robinrath/pixel-press-draw-yourown-video-game [8] Wikipedia. Microsoft HoloLens. https://en.wikipedia.org/wiki/Microsoft_HoloLens [9] Wikipedia. Pokemon GO. https://en.wikipedia.org/wiki/Pok%C3%A9mon_GO [10] Wikipedia. Feature-driver Development. https://en.wikipedia.org/wiki/Featuredriven_development [11] Wikipedia. Flood Fill. https://en.wikipedia.org/wiki/Flood_fill 65 7. Anexo En este capítulo de anexo, se explican los diferentes algoritmos de procesamiento de imágenes que han sido investigados. La explicación se hace del funcionamiento de los algoritmos en su forma genérica. Toda adaptación que se haya hecho para las necesidades concretas del videojuego, se explica en el capítulo 4 (desarrollo). Para el videojuego ha sido necesario la investigación de algoritmos para el procesamiento de imágenes, más concretamente para la separación por regiones de la misma. Los algoritmos investigados se recogen en los siguientes apartados. 7.1. Split and merge Este algoritmo utiliza la estructura de arbol de tipo quadtree para dividir la imágen por regiones. Los quadtrees también suelen utilizarse en los videojuegos para particionar el espacio y, por ejemplo, ahorrar cálculos a la hora de calcular colisiones o de descartar elementos del escenario para que no sean dibujados por la tarjeta gráfica. Cada nodo del quadtree contiene 4 subnodos que corresponden a las sub regiones noreste, sudeste, sudoeste y noroeste. Se trata de un algoritmo recursivo y se divide en dos fases que se explican a continuación. 7.1.1. Split En la primera fase se parte de un quadtree del mismo tamaño que la imagen. Se define también un tamaño mínimo para los quadtrees. Para cada quadtree: 1) Si el tamaño del quadtree es igual o menor al tamaño mínimo, se termina el algoritmo. 2) Se divide el quadtree en 4 subnodos y se vuelve a ejecutar el algoritmo para cada una de ellas. A continuación se muestra la división de una imagen para un tamaño mínimo de 4 píxeles (cada cuadro representa un píxel): 67 FIGURA 7.1: SPLIT AND MERGE - IMAGEN ORIGINAL FIGURA 7.2: SPLIT AND MERGE - SPLIT 7.1.2. Merge La segunda fase del algoritmo consiste en ir analizando desde las hojas hasta la raiz el árbol generado siguiendo los siguientes pasos: Para cada quadtree: 68 1) Si los cuatro subnodos del quadtree son similares, se eliminan los subnodos. 2) Comprobar si el quadtree tiene un nodo padre: a. En caso afirmativo, se vuelve a ejecutar el algoritmo sobre ese nodo. b. En caso negativo, el algoritmo finaliza. Como resultado se obtiene una división como la que se muestra en la siguiente imagen: FIGURA 7.3: SPLIT AND MERGE - MERGE 7.2. Flood fill Este algoritmo, creado por S. Fazzini, suele ser utilizado en software de dibujo, para implementar el “cubo de pintura”, y en algunos videojuegos como el “Minesweeper” para determinar que fichas no tienen minas cerca. Este algoritmo requiere tres parámetros: un nodo inicial, un color para sustituir, y un color de relleno. El algoritmo rastrea los nodos adyacentes al seleccionado buscando los que tienen el mismo color que se quiere sustituir. En caso afirmativo el color de ese nodo se sustituye por el color de relleno. Suelen existir dos variantes principales, con 4 vecinos o con 8 vecinos. La diferencia es que el último también comprueba los nodos que tienen en sus diagonales. Ambas variantes se comparan en la siguiente imagen: 69 FIGURA 7.4: VARIANTES DEL ALGORITMO FLOOD FILL Se trata de un algoritmo recursivo y su implementación resulta bastante sencilla. El funcionamiento del algoritmo se resume en los siguientes pasos (para la variante de 4 vecinos): 1) Si el color del nodo es distinto del que se pretende sustituir, se termina el algoritmo. 2) Se cambia el color del nodo al de relleno. 3) Se ejecuta de nuevo el algoritmo con los mismos parámetros de color para el nodo situado: a. A la izquierda del actual. b. A la derecha del actual. c. Encima del actual. d. Debajo del actual. 4) Fin del algoritmo. Una variante típica que se suele utilizar también, es comparar los colores con un grado de tolerancia, de modo que se sustituye también el color en caso de que el nodo a sustituir tenga un color parecido al de relleno (en lugar de exactamente el mismo). A continuación se muestra un ejemplo del proceso: 70 FIGURA 7.5: PROCESO DEL ALGORITMO FLOOD FILL 71