PROGRAMACIÓN DE UN VIDEOJUEGO BASADO EN SONIDOS USANDO UNITY - Lara Viñas Martínez Tutor Antonio Pena Giménez Curso 2020/2021
←
→
Transcripción del contenido de la página
Si su navegador no muestra la página correctamente, lea el contenido de la página a continuación
PROGRAMACIÓN DE UN VIDEOJUEGO BASADO EN SONIDOS USANDO UNITY Lara Viñas Martínez Trabajo de fin de grado Escuela de Ingeniería de Telecomunicación Grado en Ingeniería de Tecnologías de Telecomunicación Tutor Antonio Pena Giménez Curso 2020/2021
Índice 1. Introducción, objetivos, estructura 1 1.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2. Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.3. Estructura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2. Estado del arte 2 2.1. Motor Gráfico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.2. Metodología . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3. Diseño software 4 3.1. Diseño de herramientas de diseñador . . . . . . . . . . . . . . . . . . . . . 4 3.2. Sincronización de las acciones del juego con la música . . . . . . . . . . . . 5 3.2.1. Tiempo en Unity . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 3.2.2. Ajuste de la latencia . . . . . . . . . . . . . . . . . . . . . . . . . . 7 3.3. Diseño de las mecánicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.3.1. Lógica de los soldados de la formación . . . . . . . . . . . . . . . . 10 3.3.2. Lógica de los soldados enemigos . . . . . . . . . . . . . . . . . . . . 11 4. Diseño del banco de pruebas y resultados 12 5. Conclusiones 13 6. Bibliografía 14 Anexos 16 A. Manual de desarrollador 16 A.1. Interfaz Unity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 A.2. ScriptableObject . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 A.2.1. Proceso de creación de un SO . . . . . . . . . . . . . . . . . . . . . 18 A.2.2. SO del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 A.3. Diagrama de objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 A.4. Diagrama UML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 A.5. GameObject de la escena . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 A.6. A* Pathfinding Project Pro . . . . . . . . . . . . . . . . . . . . . . . . . . 31 B. Pruebas 33 B.1. Pruebas realizadas para validar la lógica de los soldados en formación . . . 34 B.2. Pruebas realizadas para validar la lógica de los soldados enemigos . . . . . 34 B.3. Pruebas realizadas para el ajuste de la latencia . . . . . . . . . . . . . . . . 35
C. Manual de usuario 35 C.1. Elementos del juego . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 C.2. Cómo empezar a jugar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
1. Introducción, objetivos, estructura 1.1. Introducción El desarrollo de un videojuego consta de unas fases, empezando con la concepción de la idea y finalizando con la distribución y mantenimiento del producto final. En la industria del videojuego es muy habitual emplear metodologías ágiles para el desarrollo de estas fases y más en concreto basadas en Scrum[1]. En el desarrollo de un videojuego se involucran profesionales de diferentes ámbitos como el de la programación, diseño, música, arte, etc. El equipo humano de este proyecto se completa con Jacobo Ulloa Vázquez, diseñador del proyecto y cuya labor se expone en el Trabajo de Fin de Grado Diseño de un videojuego: Legiofvnk [2]. De este modo, las tareas de cada fase se asocian según la especialidad profesional, distinguiendo entre tareas de diseñador y programador. Debido al reducido grupo humano de trabajo y la motivación del proyecto se centran los esfuerzos en las fases de concepción de la idea, diseño, planificación y producción, obviando las fases de distribución/Marketing y mantenimiento. La primera fase consiste en conformar los aspectos fundamentales, en donde destaca la elaboración de un storyboard con el cual comenzar a diseñar. Esta primera fase la lleva a cabo el diseñador y una vez finalizada se trabaja conjuntamente en el diseño del juego. La creación de la historia, definición de las mecánicas, diseño de personajes, diseño de ambientes, diseño de música y en general la definición del arte del juego, se realizan en la fase de diseño y por el diseñador. Una vez se realiza parte de estas el programador comienza a describir la manera en la que se implementará el videojuego y la metodología a seguir. Finalmente, mediante la definición del pipeline (flujo de trabajo, procesos de produc- ción o cadena de producción) se comienza y avanza en la producción del videojuego hasta culminar el proyecto con la obtención de un prototipo. 1.2. Objetivos El objetivo principal de este Trabajo de Fin Grado es desarrollar un prototipo pre- alfa del primer nivel del videojuego. Con este se pretende ilustrar el concepto de idea del diseñador y sus reglas básicas. Además, la consecución de un prototipo permitiría obtener experiencia de usuario y extraer conclusiones con las cuales determinar las líneas futuras de desarrollo. Inherente al objetivo principal y al carácter colaborativo del proyecto se definen los siguientes objetivos específicos: Realizar un diseño de programación flexible pero independiente a las ta- reas del diseñador. El desarrollo de tareas en paralelo puede provocar futuras modificaciones de diseño, pero no deben influir en el curso de la producción. Es fun- damental que el diseño de programación contemple como solventar posibles ajustes sin la necesidad de realizar cambios en código. 1
Programar las mecánicas que constituyen el funcionamiento general del videojuego. Con la programación de las mecánicas se definen las reglas del juego y se proporciona una visión aproximada de la idea inicial. Ajustar el efecto de los retardos en la experiencia del usuario. En el vi- deojuego desarrollado el control de los personajes se realiza mediante la pulsación de teclas a ritmo de la banda sonora del juego. La latencia auditiva y visual debido a los componentes hardware, junto con el retardo de acción del usuario al estímulo sonoro, provocan una latencia acumulada considerable. Se debe reducir al máximo el efecto de esta sobre el usuario y evitar posibles frustraciones por la imposibilidad de predecir el tiempo de pulsación correcto. 1.3. Estructura En los siguientes capítulos se recopila el proceso de documentación y ejecución del proyecto. En el capítulo 2 se presenta una breve descripción sobre el contexto actual del desarrollo de videojuegos, se presentan las tecnologías más populares del momento y se describe la metodología de trabajo habitual en la industria. En el capítulo 3 se explica el diseño de programación, introduciendo la idea y mecá- nicas del juego, la estructuración de la problemática y las soluciones realizadas para el desarrollo de la idea y consecuente proyecto. Posteriormente, en el capítulo 4 se presentan las pruebas realizadas y resultados ob- tenidos, concluyendo, en el capítulo 5 con la determinación de los objetivos alcanzados y líneas futuras de desarrollo. Cabe mencionar que al final del documento se halla la bibliografía revisada y un apartado de Anexos con información complementaria sobre el trabajo que se ha llevado a cabo. 2. Estado del arte El desarrollo de un videojuego es una actividad multidisciplinar en la que participan diseñadores, artistas, escritores, ingenieros, jefes de proyecto, etc. El grupo humano de trabajo en los grandes estudios de videojuegos sobrepasan los miles de personas, por ejemplo, en The Last of Us 2 (2020), desarrollado por Naughty Dog se contabilizan 2.332 personas implicadas [3]. Sin embargo, cada vez es más habitual la presencia de los videojuegos independien- tes, popularmente conocidos como Indies, que son desarrollados por grupos reducidos de individuos o empresas pequeñas. El juego 7 Days to Die (2013), catalogado como Indie y desarrollado por la empresa The Fun Pimps, contó con un total de 31 personas para su desarrollo y obtuvo una gran aceptación [4]. El auge de la producción de juegos independientes se debe principalmente a la creación de Steam [5], una plataforma de distribución digital de videojuegos creada por Valve en 2003. Esto junto a la democratización de los motores gráficos hace que el interés por el desarrollo de videojuegos vaya en aumento y que las tecnologías y metodologías tengan mayor divulgación. 2
2.1. Motor Gráfico Para el desarrollo de un videojuego es indispensable contar con un programa software que permita su creación, o lo que es lo mismo un motor gráfico. Normalmente, este ofrece al programador un motor de renderizado para gráficos 2D y/o 3D, un motor para detectar la colisión física de objetos y la respuesta a dicha colisión, scripting, sonido, animación, inteligencia artificial, gestión de memoria o la posibilidad de comunicarse con la red para juegos multijugador. La elección del motor gráfico dependerá de tres factores esencialmente: la capacidad gráfica, la facilidad de desarrollo y la accesibilidad. Actualmente, los motores con mejor capacidad gráfica y de fácil acceso son Unreal Engine, perteneciente a la compañía Epic Games y Unity, desarrollado por Unity Technologies [6][7]. Unreal Engine es un motor con un acabado gráfico inicial mejor al de Unity, con el que se desarrolló el popular juego de Fortnite (2017). Sin embargo, Unity es el motor predilecto de los desarrolladores independientes y existen multitud de tutoriales y foros especializados de los que obtener información. Dada las dimensiones del proyecto se considera que la capacidad gráfica de Unity es más que suficiente. Con este motor se han desarrollado videojuegos con una gráfica infinitamente superior al que se plantea, como por ejemplo Pokémon Mystery Dungeon: Rescue Team DX (2020). La amplia información disponible se considera de gran valor a la hora de producir el videojuego y se elige como el motor idóneo para llevar a cabo este proyecto. Cabe destacar que, actualmente, el motor gráfico por excelencia respecto a la capa- cidad gráfica es CryENGINE, desarrollado por Crytek e introducido con su primer Far Cry (2004). Por contra, es un motor de pago y de alta complejidad en el desarrollo de proyectos. 2.2. Metodología Al comenzar el diseño de un juego en el motor gráfico lo más habitual es seguir la práctica de Grayboxing [8]. Esta práctica de diseño consiste en simular mediante geome- trías sencillas y sin texturas, una versión simple de la idea que se tiene en mente. En el caso de este proyecto, por ejemplo, existen dos ejércitos en combate, en un principio los soldados de un ejército se representan por cubos y los del otro por esferas. Una vez se finaliza el diseño en GrayBoxing se pueden utilizar los elementos creados como placeholders [9][10] (marcadores de posición). Los placeholders deben usar el nombre y la resolución definitivos y establecerse en la posición final, de este modo su sustitución por los elementos finales es inmediata. La utilización de estos permite desarrollar toda la lógica del juego en ausencia del trabajo artístico, en consecuencia, el diseño de los elementos finales del juego y la programación de la jugabilidad se pueden realizar en paralelo. Para construir los elementos que conforman el juego con mayor detalle de diseño, las compañías de videojuegos emplean programas o extensiones más específicas que se compactan finalmente en el motor gráfico. 3
Por tanto, en la fase de producción de este proyecto se elabora el diseño de Grayboxing y los consiguientes placeholders que permiten programar las mecánicas del juego. En paralelo el diseñador realiza el trabajo de arte, diseñando los elementos finales, que se incorporan en última instancia al proyecto. 3. Diseño software Cuando el diseñador desarrolla el concepto de idea se obtiene una visión del juego lo suficientemente clara como para iniciar el diseño de programación. A continuación se explica brevemente el funcionamiento del videojuego y sus mecánicas como preludio al diseño de programación. Legiofvnk es un juego de guerra y estrategia donde el usuario, en el primer nivel, controla una formación de 9 unidades en disposición 3x3. El usuario puede mover la formación, atacar a los soldados enemigos y cambiar de formación pulsando ciertas teclas. Estas acciones de usuario se ejecutan si la pulsación de las teclas se produce a ritmo de la música y se dan las condiciones de camino despejado o enemigo a distancia de ataque. En el juego se establece como prioritaria la acción de atacar, por lo que si un soldado se encuentra a distancia de ataque, realiza el ataque y la formación no se mueve. Los enemigos realizan las mismas acciones que las del usuario pero de forma individual, no en formación y cada dos pulsos del tema musical. La condición de victoria en este primer nivel es eliminar al jefe del ejército enemigo. Como la programación del juego se realiza en paralelo al diseño y puede estar sujeta a cambios, se decide realizar un diseño de programación modular. Esto permite que las funcionalidades sean claramente diferenciables y modificables sin que repercutan unas entre otras. Se comienza el diseño elaborando los placeholder que permiten conformar los elemen- tos del videojuego, con los nombres y estructuras de directorios finales en una versión muy básica. De este modo se proporciona al diseñador las herramientas necesarias para el ajuste del juego. Además, se observa que el funcionamiento del juego presenta dos partes claramente desacopladas, la parte rítmica y la parte de las mecánicas. Se decide por tanto desglosar el diseño del proyecto en un total de tres partes: 1. Diseño de herramientas de diseñador. 2. Sincronización de las acciones del juego con la música. 3. Diseño de las mecánicas. 3.1. Diseño de herramientas de diseñador La interactividad y jugabilidad desarrollada en Unity se construye sobre tres pilares fundamentales: GameObjects, componentes y variables. 4
Un GameObject es cualquier objeto que forma parte del juego al que se le agregan com- ponentes para asignarles las propiedades que lo caracterizan. Los componentes se definen por unas variables que se pueden modificar en la ventana del Inspector de Unity(Anexo A.1) o por medio de un script. La lógica y comportamiento del juego se realiza usando scripts que se agregan como componentes a los GameObject. Sin embargo, Unity dispone de la clase ScriptableObject (SO) que permite almacenar grandes cantidades de datos y facilita la gestión de cambios y depuración. Mediante la clase SO se definen las variables que caracterizan a los elementos del juego susceptibles a cambios. Estos elementos son los soldados, los ataques, los objetos recogibles y las piezas que conforman el mapa. Se adjunta en el Anexo A.2 información de la clase SO, así como, los SO creados para este proyecto que permiten al diseñador ajustar el juego A través del acceso a memoria y lectura de las variables de los SO se elaboran las listas que almacenan la información necesaria para desempeñar la lógica del juego. Estas listas son la de los soldados de la formación, los soldados enemigos, los objetos recogibles y las piezas del mapa que representan obstáculos. De este modo se permite realizar modificaciones a partir de los SO sin que suponga un problema en la programación de la jugabilidad. 3.2. Sincronización de las acciones del juego con la música Las acciones de usuario son válidas exclusivamente si la pulsación de la tecla se realiza a ritmo del tema musical. Por tanto es necesario conocer en qué pulso se halla la canción y comprobar que la acción del usuario coincide en tiempo con este. Sin embargo, la precisión en predecir y reaccionar a un estímulo no es inmediata. Esto puede provocar que algunos usuarios pulsen una tecla antes de que ocurra el pulso o inmediatamente después de que ocurra. También puede suceder que el usuario pulse una tecla a ritmo pero el retardo de los componentes hardware invalide la predicción del usuario. En consecuencia, para la sincronización se necesita: 1. Determinar la posición del último pulso. La duración del pulso (T ) se calcula a partir de los bpm (beats per minute) y compás de la música. T =bpm/(60*compás) Si se conoce el tiempo transcurrido de la canción (timeSong), implícitamente se sabe cuando tuvo lugar el último pulso (lastPulse). Para obtener el valor de timeSong se estudia las posibilidades que ofrece Unity con respecto al tratamiento del tiempo. 2. Ajustar la latencia. Se debe evitar la frustración del jugador y conseguir que se sienta recompensado por su precisión. 5
3.2.1. Tiempo en Unity En Unity se puede obtener información sobre el tiempo a través de la clase Time [11] y sus propiedades estáticas. Además, se puede reproducir, parar y extraer parámetros de una pista con la clase AudioSource y acceder al sistema de audio mediante la clase AudioSettings. Las propiedades más relevantes de las clases citadas para el proyecto son: Time.deltaTime. Devuelve los segundos transcurridos desde el último fotograma y el fotograma actual. AudioSource.Play . Permite reproducir un clip de audio. AudioSettings.dspTime. Retorna un valor en segundos a base de las muestras procesadas por el sistema de audio y por lo tanto, es más precisa que el tiempo obtenido mediante la propiedad de la clase Time. El valor que retorna es siempre el inicio del bloque de lectura. El valor de timeSong se puede ver como la acumulación de tiempo que transcurre entre cada fotograma. Por tanto, en cada fotograma se lee el valor de Time.deltaTime y se suma al valor de timeSong. Cada vez que esta suma se iguala a los múltiplos de T implica que tuvo lugar un nuevo pulso y se actualiza el valor de lastPulse. Time.deltaTime se actualiza en el hilo de Unity, es decir, como el juego funciona a 60 fps (frames per second o fotogramas por segundo) las actualizaciones de fotograma se realizan a 1/60 fps que son ∼16 ms. Sin embargo, el audio se ejecuta en un hilo independiente y la lectura de muestras depende del tamaño del buffer y del tiempo de muestreo. El tamaño de buffer es de 10241 muestras y la frecuencia de muestreo de 48 kHz, por tanto con AudioSettings.dspTime se obtiene un bloque nuevo de lectura cada ∼21.33 ms. En consecuencia, con cada actualización de Time.deltaTime es imposible leer la tota- lidad del bloque de audio y en ocasiones el valor de AudioSettings.dspTime será el mismo en dos fotogramas diferentes [12], tal y como se observa en la Figura 1. Esto provoca pequeñas desincronizaciones en la estimación del timeSong con respecto a la lectura real del reproductor de audio. Para mantener esta desincronización controlada, en el momento que el valor de timeSong difiere de la lectura real un total de ∼21.33 ms se establece como valor de timeSong el de AudioSettings.dspTime. En este punto se tiene una estimación del timeSong lo suficientemente precisa con la cual obtener el valor de lastPulse. 1 Unity ofrece tamaños de buffer de 256 y 512 muestras que presentan mejores prestaciones en cuanto a la latencia. Sin embargo, en el sistema operativo Windows el audio con estos tamaños de buffer se vuelve inestable retardando en exceso. Se desconocen las causas y Unity no ofrece una solución. 6
Figura 1: Representación de la actualización de lectura de audio en el sistema de audio y en cada fotograma, arriba y abajo, respectivamente. En cada lectura de fotograma se puede ver que no es capaz de actualizar al ritmo del sistema de audio y se obtienen muestras iguales en algunos fotogramas consecutivos. 3.2.2. Ajuste de la latencia Las conexiones entre equipos hardware ocasionan un retraso debido a la adaptación de señales. Además, el usuario contribuye con su propio retraso desde que percibe el sonido, lo interpreta y reacciona. En la Figura 2, se ilustran los factores implicados en el proceso del juego y los motivos del retardo. El correcto ajuste del retardo del equipo hardware sería a través de pruebas de me- dición antes de jugar, como se hace en Guitar Hero [13]. Sin embargo, en este proyecto no se tienen los medios para realizar dichas pruebas y a los usuarios finales tampoco se les concede el equipo necesario para su propio ajuste. Es por tanto que se realiza una estimación. El retardo entre CPU (Central Processing Unit) y altavoz (punto 1 Figura 2), se considera oportuno estimarlo en conjunto con el de la reacción del usuario. El retardo entre el teclado y CPU (punto 4 Figura 2), se considera más crítico que el de CPU y monitor, (punto 5 Figura 2), por la presencia del procesado de Unity y se ofrece una estimación conjunta calculada a partir del primero. La actualización de fotogramas, como se explicó anteriormente, se produce cada ∼16 ms. Si el usuario pulsa una tecla en un fotograma pero el retraso eléctrico hace que llegue en el siguiente, como mínimo, este retraso será el de la actualización de fotograma. Se estima, por tanto, un retraso aproximado mínimo de 20 ms entre los puntos 4 y 5 de la Figura 2. Los retardos del usuario son más controlables ya que los pulsos son periódicos en el tiempo y es suficiente con aplicar unos umbrales inferior y superior, como se muestra en la Figura 3. En el ajuste de estos parámetros se percibe que el tiempo de pulsado de una 7
tecla se produce con mayor probabilidad después de la ocurrencia del pulso, es por eso que el umbral superior es ligeramente mayor al inferior. Cuando el usuario pulsa una tecla se sigue el siguiente proceso para determinar que la acción es válida o no: 1. Se obtiene el valor de timeSong y se le restan los 20 ms estimados para el ajuste de la latencia de equipos hardware. 2. Se verifica que el tiempo resultante en 1 se halla entre los umbrales inferior y superior que determinan si la acción se realiza a ritmo. 3. Si se cumple 2 se ejecuta la lógica del juego. Figura 2: Relación de los elementos hardware con el usuario y retardos ocasionados. Figura 3: Solución mediante umbrales al retraso ocasionado en los puntos (1), (2) y (3) de la Figura 2. 8
3.3. Diseño de las mecánicas Todas las acciones se llevan a cabo cuando sucede un pulso o se pulsa una tecla, por tanto lo más eficiente es la programación de eventos. De este modo cuando se pulsa una tecla o sucede un pulso, inmediatamente se llama a un evento principal que gestiona la llamada a los demás eventos. En la Figura 4, que recoge la versión simplificada del diagrama de objetos (ver Anexo A.3 para observar diagrama de objetos completo), se observa que al pulsar una tecla a ritmo (PushButton), se llama al evento principal (EventActionsController ). Este realiza las llamadas según la prioridad de las mecánicas, por tanto primero comprueba la posibi- lidad de atacar (EventAttackController ) y en, caso contrario, se comprueba si es posible avanzar (EventCheckMovement). Además, el evento principal también llama al evento que gestiona el cambio de for- mación (ControllerFormation) cuando se pulsan las teclas correspondientes. El proceso de estos eventos, con las clases implicadas se ilustra en el diagrama UML simplificado de la Figura 5 (ver Anexo A.4 para observar diagrama UML completo). Sin embargo, para mayor claridad se detalla el funcionamiento de la lógica diferenciando entre los soldados que maneja el usuario y los soldados enemigos. Figura 4: Diagrama de objetos simplificado. 9
Figura 5: Diagrama UML simplificado. 3.3.1. Lógica de los soldados de la formación Un usuario cuando pulsa las teclas de dirección es porque quiere atacar a un enemigo o moverse, por tanto debido a las mecánicas del juego, primero se comprueba si hay un enemigo a distancia de ataque. Para ello se comparan las posiciones futuras de cada soldado de la formación con la posición de todos los enemigos de la escena. Si hay un enemigo en una posición futura se ejecuta el ataque correspondiente, en caso contrario, se comprueba si es posible avanzar, comparando las posiciones futuras con la posición de todos los obstáculos de la escena. En la Figura 6 se muestra un ejemplo de la lógica desarrollada. En cambio si el usuario pulsa Q, W o E indica que quiere realizar un cambio de formación y se llama al evento en cuestión. La posición de los soldados en la formación se puede ver como una matriz cuyos índices tienen el valor del identificador del soldado. A través de la permutación de filas y columnas de la matriz se obtiene el posible cambio de formación y, por consiguiente, las futuras posiciones de los soldados. En la Figura 7 se representa con más detalle lo expuesto. Las futuras posiciones serán válidas si no hay un soldado enemigo o un obstáculo en dichas posiciones, y por tanto, se actualiza la posición de los soldados cambiando la formación. La comparación de posiciones es posible a través de la lectura de las listas que se confeccionan a partir de la lectura de los SO. Las listas son: soldados de formación, 10
soldados enemigos y obstáculos. En ellas se almacenan, entre otras variables, la posición de cada elemento. Figura 6: Esquema de la lógica del juego. a) Se pulsa tecla de dirección adelante, no se halla enemigo entre las posiciones futuras pero sí un obstáculo, no se realiza ninguna acción. b) Se pulsa tecla de dirección derecha, no se halla enemigo ni obstáculos entre las posiciones futuras, la formación avanza una posición. c)Se pulsa tecla de dirección adelante, se halla enemigo entre las posiciones futuras, se ataca.. Figura 7: Representación de los cambios de formación. a) Matriz que representa la posición inicial y a partir de la cual se realizan los cambios en b), c) y d). b) Tecla pulsada Q, las unidades de la primera fila pasan a la última y las otras se desplazan en consecuencia. c) Tecla pulsada W, las unidades de la primera columna pasan a la última y las otras se desplazan en consecuencia. d) Tecla pulsada E, las unidades rotan su posición en el sentido de las agujas del reloj.. 3.3.2. Lógica de los soldados enemigos Un soldado enemigo debe atacar siguiendo los siguientes criterios: 11
1. Al soldado más cercano. 2. En caso de 2 o más soldados a la misma distancia se ataca al soldado de menor vida. 3. En caso de coincidencia en el valor de la vida se ataca al soldado con mayor fuerza. 4. Si los dos soldados tienen la misma fuerza se elige uno al azar. Existen cuatro direcciones permitidas de ataque, por tanto, cuatro posiciones futuras que deben ser comparadas con todos los soldados de la formación. Se comienza compa- rando la primera posición futura del enemigo, en caso de que un soldado de la formación se halle en esta posición futura se guarda la información de este y la distancia a la que se encuentra. Si en la siguiente posición futura también existe coincidencia, quiere decir que un enemigo tiene al menos a dos soldados a distancia de ataque. Por tanto se comparan los soldados y se guarda la información del soldado que cumpla el criterio más restrictivo. Se realiza el paso anterior para las dos restantes posiciones futuras. De no existir coincidencias el enemigo se debe mover siguiendo los mismos criterios de ataque. Para ello se debe averiguar a qué distancia se encuentra el enemigo de todos los soldados de la formación, es decir hallar el mejor camino. Para la búsqueda de caminos se usa el asset A* Pathfinding Project Pro (Anexo A.6) desarrollado por Aron Granberg y disponible en versión libre. Se basa en un algoritmo A*2 que permite obtener el número de nodos que separan al enemigo de cada soldado. El soldado que se encuentre a menor distancia de número de nodos es el más cercano y hacia el que se avanza. Si existen varios soldados a distancia igual número de nodos se dirige hacia aquel que cumpla el criterio más restrictivo de los explicados anteriormente. 4. Diseño del banco de pruebas y resultados La validación del juego se hace a medida que se va programando la lógica, detectando anomalías en la interacción de los elementos y ajustando parámetros. Para realizar el ajuste más rápido se agrega un componente a los soldados que le proporcionan vida infinita, denominado Modo Dios 3 . Además, en los soldados enemigos se agrega una variable que permite inmovilizarlos y en los soldados de la formación una variable que permite matarlos. Alguna de las pruebas realizadas empleando estas tres herramientas son: 1. Con los enemigos quietos y en Modo Dios se verifica que los soldados de la formación atacan a los soldados enemigos, solo si estos se encuentran a distancia de ataque. 2 El algoritmo A* conocido como «A-Star» es una modificación optimizada del algoritmo Dijkstra. Se clasifica dentro de los algoritmos de búsqueda en grafos. Su función es encontrar siempre y cuando se cumplan determinadas condiciones, el camino de menor costo entre un nodo origen y uno objetivo. 3 Opción o truco incluido en ciertos juegos que otorga inmortalidad, y por tanto la imposibilidad de perder. Se suele desbloquear al completar el juego, o al introducir códigos especiales. A menudo es empleada por los desarrolladores y probadores de videojuegos para realizar labores de testeo en el juego 12
2. Con la misma configuración anterior se prueba que aunque un enemigo se halle a distancia de ataque este no es atacado porque hay un obstáculo en medio. 3. Con todos los soldados de la formación en Modo Dios y sin pulsar tecla alguna, dejar que la lógica de los enemigos funcione, comprobando que los soldados se mueven y atacan según los criterios establecidos. 4. Se verifica que los soldados no atraviesen obstáculos. 5. Con los enemigos inmóviles y matando soldados de la formación estratégicamente se comprueba que los cambios de formación se efectúan correctamente. 6. Se comprueban las condiciones de victoria con los soldados enemigos inmóviles y avanzando hasta el enemigo jefe del nivel que con su muerte se asegura la victoria. En cuanto al ajuste de los umbrales inferior y superior que proporcionan al usuario mayor capacidad de acertar el ritmo de la canción, se lleva a cabo a base de la experien- cia personal con el juego. Sin embargo el ajuste final depende, en este proyecto, de la apreciación del diseñador. En el Anexo B se adjuntan de forma detallada las pruebas realizadas en esta fase de testeo. 5. Conclusiones El objetivo principal se cumple con el desarrollo del primer nivel del juego [14] [15] que ejemplifica el concepto inicial del diseñador. En este prototipo pre-alfa se programan las mecánicas que constituyen las reglas del juego, cumpliendo de esta forma uno de los objetivos específicos. El desarrollo del prototipo se lleva a cabo con placeholders, que a posteriori el di- señador reemplaza por los elementos finales. La programación flexible a través de SO, permite realizar ajustes de diseño en paralelo a la programación de la lógica. Por tanto se ha logrado el objetivo específico de independizar las tareas de los miembros implicados. Además, el juego provoca una experiencia de usuario satisfactoria entre los miembros del equipo, considerando correcto el ajuste de las latencias y cumpliendo con este, el último de los objetivos específicos. Sin embargo, el diseñador tiene en mente que el juego tenga 26 niveles, en los cuales la complejidad va en aumento y donde aparecen nuevos elementos, nuevos terrenos, nuevas habilidades en los soldados, etc. La principal línea futura sería continuar con el desarrollo del juego hasta su totalidad y obtener un producto final. La consecución de un producto final implicaría la optimización del código, principal- mente de la búsqueda de caminos en la lógica de los enemigos y del ajuste de umbrales en la parte rítmica del juego. En cuanto a la búsqueda de caminos se podría seguir dos vertientes: elaborar un algoritmo A* propio y exclusivo para las necesidades del juego o adquirir la versión de 13
pago del asset A* Pathfinding Project Pro, que permite la comparación entre múltiples destinos y la ejecución en multihilos. La parte rítmica del juego es un factor muy influyente en la experiencia de usuario, por tanto se podría afinar el ajuste de los umbrales usando el prototipo pre-alfa en pruebas de ensayo con usuarios externos. 6. Bibliografía Referencias [1] _. Proyectos ágiles. [Online]. Dirección:https://proyectosagiles.org/que-es-scrum/. [2] J. Ulloa Vázquez. "Trabajo de Fin de Grado". Dirección:https://drive.google.com/drive/folders/154fnr7o6FwElWkx- Tm3Wu4xxJIwFNstx?usp=sharing. [3] VidaExtra. (2020,7,28). “¿Cuántas personas trabajan en los juegos de gran presu- puesto como the last of us 2, god of war o gears 5?”. [Online]. Dirección: https://www.vidaextra.com/industria/cuantas-personas-trabajan-juegos-gran- presupuesto-como-the-last-of-us-2-god-of-war-gears-5. [4] C. Steam. (2018,6,30). “The size of tfp development team as stated by roland”. [Online]. Dirección: https://steamcommunity.com/app/251570/discussions/0/1727575977560429112/. [5] Steam. (1996,8,24). “Plataforma digital de videojuegos”. [Online]. Dirección: https://store.steampowered.com/. [6] M. Delgado. (2021,12,2). “Los 11 mejores motores gráficos para introducirse en el desarrollo de videojuegos”. [Online]. Dirección: https://vandal.elespanol.com/reportaje/los-11-mejores-motores-graficos-para- introducirse-en-el-desarrollo-de-videojuegos. [7] D. Emegé. (2,12,2021). “Los motores de juegos más importantes de todos los tiempos”. [Online]. Dirección: https://www.3djuegos.com/juegos/articulos/1662/0/los-motores-de-juegos-mas- importantes-de-todos-los-tiempos/. [8] R. Yang. (2017,9,14). “How to graybox, blockout a 3D videogame level”. [Online]. Dirección: https://www.blog.radiator.debacle.us/2017/09/how-to-graybox-blockout-3d-video- game.html. [9] GamerDic. (2015,2,3). “Placeholder”. [Online]. Direc- ción:https://www.gamerdic.es/termino/placeholder/. [10] B. Smith. “Placeholders in games”. [Online]. Dirección:http://xnameetingpoint.weebly.com/placeholders-in-games.html. 14
[11] Unity. “Manual time”. [Online]. Dirección: https://docs.unity3d.com/ScriptReference/Time.html. [12] R. Forum". “How do rhythm games stay in sync with the music?”. [Online]. Dirección: https://www.reddit.com/r/gamedev/comments/13y26t/how_do_rhythm_games_stay_in_sync_ [13] H. Music System. “Harmonix support videos - calibration”. [Online]. Dirección: https://www.youtube.com/watch?v=MoUIQr2pTAw. [14] Drive. “Videojuego Legiofvnk”. [Online]. Dirección:. https://drive.google.com/drive/folders/1dJVA-tAJEARV8za4qvzIYYs0FiGUvxkH?usp=sharing. [15] "Github". “CodeOfGameLegiofvnk”. [Online]. Direc- ción:https://github.com/Laravinas92/codeOfGameLegiofvnk.git. [16] A. Granberg, “A* Pathfinding Project Pro”. [Online]. Dirección: https://assetstore.unity.com/packages/tools/ai/a-pathfinding-project-pro-87744. [17] Daniel. “Unity - A* Star Pathfinding tutorial”. [Online]. Direc- ción:https://www.youtube.com/watch?v=AKKpPmxx07w. [18] Brackeys. 2D Pathfinding - enemy AI in Unity”. [Online]. Direc- ción:https://www.youtube.com/watch?v=jvtFUfJ6CP8. 15
Anexos A. Manual de desarrollador A.1. Interfaz Unity La interfaz de Unity consta de una serie de ventanas principales desde las que se controla y ejecuta el desarrollo del videojuego. Ventana Project (Proyecto). En esta vista se encuentran los assets importados o creados del proyecto listos para ser usados o editados. Ventana Hierarchy (Jerarquía). La ventana Hierarchy contiene los objetos de la escena actual, los GameObject (GO). Se puede, entre otras funciones, ocultar y emparentar GO en la escena. Toolbar (Barra de herramientas). Contiene comandos para ejecutar, detener y pausar la escena y otros para manipular los GO como rotar y mover. Ventana Inspector. El inspector permite ver las propiedades de un GO seleccio- nado y agregarle componentes. Ventana Scene View (Escena). Es la vista donde se incorporan los GO y se manipulan para crear la escena de un juego. Ventana Game (Juego). Sección donde se puede ver una vista previa de cómo será el juego finalizado. Figura 8: Ventana Project y Toolbar, arriba y abajo, respectivamente. 16
Figura 9: Ventana Hierarchy e Inspector, izquierda y derecha, respectivamente. Figura 10: Ventana Scene y Game, arriba y abajo, respectivamente. 17
A.2. ScriptableObject Un ScriptableObject (SO) es un tipo especial de objeto que se puede usar para alma- cenar grandes cantidades de datos, que no son alcanzables por los GO y que residen en memoria. El principal beneficio de un SO es que son editables en tiempo de ejecución del juego, reducen el uso de memoria y evitan la duplicación de datos. Para utilizar un SO se crea un script y se hace heredar de la clase ScriptableObject. Utilizando el atributo CreateAssetMenu se pueden crear los assets personalizables a través de la barra de menú de la aplicación o mediante el menú desplegable Create de la ventana Project. Una vez creado se puede cambiar el nombre, moverlo a otra carpeta, rellenarlo con los datos personalizados, etc. Se decide dividir la presentación de este Anexo en dos partes para mayor claridad. En el Anexo A.2.1 se explica el proceso de creación de un SO y en el A.2.2 se disponen la totalidad de los SO creados y empleados en el juego. A.2.1. Proceso de creación de un SO Se ilustra mediante el SO creado para los objetos recogibles el proceso de creación de un SO. En la Figura 11 se define el script del SO para almacenar los objetos recogibles emplea- dos en el juego. Estos objetos se caracterizan por tener un nombre y una cantidad de vida o dinero, por tanto, en el script se definen dos variables asociadas a estas características. Una vez definido el SO con las variables que componen al objeto se pueden crear SO de esta clase, tal y como se procede en la Figura 12. Un SO se crea con la estructura definida en el script pero sin valores. En la Figura 13 se puede ver un ejemplo de un SO inicial sin valores y el utilizado para este proyecto. Figura 11: Script que permite definir un SO de tipo DataBaseItems. 18
Figura 12: Creación del SO desde la barra de menú de la aplicación y su ubicación en la carpeta de Assets de la ventana Project, arriba y abajo, respectivamente. 19
Figura 13: Apariencia de un SO de la clase DataBaseItems nada más crearlo y el SO final de los objetos recogibles utilizado en el juego, izquierda y derecha, respectivamente. A.2.2. SO del proyecto Para el proyecto se definen las siguientes clases que heredan de ScriptableObject: DataBaseAttacks. Una de las características de los soldados es la técnica de com- bate que poseen. Existen cuatro tipos de ataque que se diferencian entre sí por su alcance. En la Figura 14 se presentan los cuatro SO creados de esta clase. Además, en este se disponen los métodos que comprueban si un soldado se encuentra a la distancia de ataque y que son utilizados en el evento atacar. DataBaseSoldiers. Las variables que definen a un soldado son básicas para el desarrollo de las mecánicas del juego. Existen un total de 11 tipos de soldados cuyos parámetros se pueden personalizar a través de los pertinentes SO. En la Figura 15 se halla un ejemplo del SO legionario y los parámetros que lo definen. DataBaseItems. Permite almacenar los objetos recogibles con los que un soldado de formación puede interactuar. Se puede consultar en la Figura 16. DataBaseScenary . En este se almacenan los materiales que permiten al diseñador crear y personalizar el mapa del primer nivel. En la Figura 17 se ilustra un extracto de este. DataBaseFormation. Los soldados de la formación no se ubican en la escena en el momento de edición. En los futuros niveles del juego el usuario puede configurar la 20
formación a su gusto y por tanto, no es viable disponer una formación determinada en escena. Estos soldados se ubican en escena a través del acceso al SO de la clase DataBaseFormation y se puede consultar en la Figura 18. Figura 14: SO de la clase DataBaseAttacks creados para el proyecto y las variables que lo definen, izquierda y derecha, respectivamente. 21
Figura 15: Conjunto de SO creados a partir de la clase DataBaseSoldiers y visualización de las variables personalizables en la ventana del Inspector, arriba y abajo, respectivamente. 22
Figura 16: SO de la clase DataBaseItem empleado en el desarrollo del videojuego. Figura 17: SO de la clase DataBaseScenary que almacena los materiales que componen el mapa del primer nivel. 23
Figura 18: SO de la clase DataBaseFormation donde se almacenan los soldados que con- trola el usuario y como se dispone la formación A.3. Diagrama de objetos El diagrama de objetos se realiza en la fase de diseño de programación para indicar qué objetos principales se disponen en escena y la dependencia existente entre los mismos. La Figura 19 recoge el diagrama de objetos de este proyecto. 24
Figura 19: Diagrama de objetos del proyecto. A.4. Diagrama UML La estructura del proceso del proyecto se plasma a través de la realización del diagrama UML, tal y como se puede ver en la Figura 20. 25
Figura 20: Diagrama UML del proyecto. A.5. GameObject de la escena Los GO que componen la escena del primer nivel se pueden consultar Figura 21. Para desarrollar la lógica del juego a estos GO se le agregan unos componentes. A continuación, se explica con más detalle la función de los GO y los componentes asociados más relevantes para el desempeño de la lógica del juego. A* . Es el objeto que se encarga de la búsqueda de caminos, en el Anexo A.6 se describe con mayor profundidad. Canvas. Creando un nuevo elemento UI (Unity Interface), como por ejemplo un Button (botón), automáticamente se crea el GO Canvas. Todos los elementos UI se hacen hijos de este. No tiene relevancia en la lógica del juego. 26
EventSystem. Se crea automáticamente cuando se crea un Canvas en la escena. Permite llamar eventos cuando un elemento UI es seleccionado. Main Camara. Proporciona la vista de la escena desde la posición del jugador. Directional Ligth. GO que incorpora el diseñador para la correcta iluminación de la escena. CameraController . Se emplea para que la vista de la escena siempre se centre en la posición del jugador, es decir, que el GO Main Camara se mueva cuando lo hagan los soldados de la formación. Signal pulse. GO que se emplea de referencia en las pruebas de ajuste del ritmo. Es una luz que parpadea a ritmo de la música indicando de este modo el pulso. Controller_Rhythm. Se encarga de gestionar la parte rítmica del juego a través de los siguientes componentes: • BeatManager . Detecta el tiempo transcurrido en la canción y actualiza el valor de la posición del último pulso. • PushButton. Espera que se pulse una tecla y se comprueba que se hace a ritmo, es decir, dentro de los umbrales permitidos. En la Figura 22 se presenta la ventana del Inspector de este objeto permitiendo ver los componentes anteriormente citados. Controller_GameState. Es el GO que gestiona el cambio de escenas y por tanto, guarda parámetros compartidos entre escenas y carga la escena debida. En este pro- totipo, solo se desarrolla el primer nivel, por tanto no hay parámetros que guardar ni cambios de escena, sin embargo, se deja configurada la posible lógica de futuros niveles. Una formación configurada por el usuario en la escena menú, se debe repre- sentar en la escena del nivel, por tanto se debe guardar en memoria. A través del componente GameState se puede seleccionar entre la formación que se emplea en el primer nivel o la que se guardaría entre escenas. Se puede ver este componente en la Figura 23. Controller_SO. A través de su componente SO_Manager se leen las variables de los SO que se emplean en otros GO. Controller_Actions. Es uno de los GO más importantes en el desarrollo de las mecánicas. Contiene los principales componentes que permiten atacar y mover a los soldados, tal y como se puede ver en la Figura 24. A continuación se explican sus componentes por separado: • FindEnemies. Como su nombre indica, nada más empezar el juego, busca los soldados que hay en escena y se crea una lista donde se guarda toda su infor- mación. Este también gestiona los cambios de vida y posición de los mismos. • FindObjects. Busca los objetos no transitables y recogibles de la escena y se crean sendas listas. Además gestiona todo lo relativo a ello, como la cantidad de golpes que faltan para destruir un objeto o la aparición de nuevas recompensas en el mapa. 27
• EventActionsController . Es el evento principal que se llama cuando se pulsa una tecla o sucede un pulso. A partir de este se llaman a los demás eventos. • EventAttackController . Se llama a este evento para comprobar si se puede atacar a un soldado. • EventCheckMovement. Es el evento que comprueba si el movimiento de los soldados de la formación se puede realizar. • ModifyIconLife. La vida de los soldados se representa por unos corazones que se decrementan si te atacan o incrementan si adquieres vida como recompensa. Es este componente el que se encarga de representar este efecto en la escena. • IADestination. Es el componente que permite al enemigo ir hacia el soldado adecuado, siguiendo los criterios de movimiento. Es decir, examina la distancia que separa a un enemigo de todos los soldados de la formación, en caso de coin- cidencia se queda con el de menor vida. Si coinciden también en este parámetro se queda con el más fuerte y si coinciden nuevamente se elige al azar. Una vez que se tiene el mejor destino se puede actualizar la posición del enemigo. Scenary . Agrupa todas las piezas o casillas que conforman el mapa. Casilla_X_Y . Como su nombre indica hace referencia a una casilla del mapa. Su componente principal es SelectMaterial que permite al diseñador fijar las siguientes variables: • Piece. Permite seleccionar la pieza actual, la que aparecerá al inicio del juego, engloba todas las piezas del juego salvo los soldados. • TransitablePiece. Permite elegir la pieza que permanecerá hasta el final del juego una vez se haya recogido la recompensa almacenada en un objeto des- truible o la ubicada estratégicamente desde el inicio de la partida. • Reward . Indica si la pieza es una recompensa. • AllowAttack . Indica si es posible atacar a través de la pieza. • Destroyable. Para indicar si la pieza es un obstáculo destruible. Habilita las siguientes variables a mayores: ◦ LifeObject. Muestra la cantidad de golpes necesarios para su destrucción. ◦ GiveReward . Permite decidir si un objeto deja recompensa o no. En caso afirmativo, se habilita la variable RewardPiece que indica el tipo de recompensa. • NotWalkeable. Permite señalizar un obstáculo. En la Figura 25 se recoge un par de ejemplos sobre la selección de estas variables. Formation. Prefab 4 que lee el SO de los soldados de la formación, los integra en la escena y crea la lista con toda la información de los soldados. Estas acciones las realiza a través del componente Formation. Además con el componente Controller- Formation se realizan los cambios de formación. Enemies. Agrupa a los soldados enemigos de la escena. 4 Un prefab es un GO pre configurado y reutilizable disponible en la carpeta de Assets. Se pueden añadir a la escena arrastrando desde la ventana de Project o por instancias vía código. 28
Enemy . Es un prefab que contiene los siguientes componentes: • Seeker . Es un componente del asset empleado A* Pathfinding Project Pro que busca el mejor camino entre un nodo origen y un destino. • EnemyIA. Inicia la búsqueda de un camino a través de la llamada al Seeker y obtiene el vector que almacena los nodos de la ruta. • SelectTypeEnemy . Permite al diseñador seleccionar el tipo de soldado. • SelectMaterial . Permite que el diseñador decida si el soldado deja recompensa o no a través de las siguientes variables. ◦ TransitablePiece. Permite elegir la pieza que permanecerá hasta el final del juego una vez se haya recogido la recompensa almacenada en el soldado enemigo. ◦ GiveReward . Permite decidir si el enemigo deja recompensa o no. En caso afirmativo, se habilita la variable RewardPiece que indica el tipo de recompensa. Figura 21: Ventana Hierarchy donde se ubican los objetos de la escena del primer nivel. 29
Figura 22: Ventana Inspector de Unity del objeto Controller_Rhythm. Figura 23: Componente GameState del GO Controller_GameState. 30
Figura 24: Componentes del GO Controller_Actions. Figura 25: Componente SelectMaterial del prefab Casilla. A.6. A* Pathfinding Project Pro La lógica del enemigo desarrollada para ir hacia el soldado más cercano emplea el asset A* Pathfinding Project Pro [16] cuya autoría pertenece a Aron Granberg. En este proyecto se utiliza la versión libre que solo permite obtener una ruta desde un origen hasta un destino. Sin embargo, en la versión de pago se comprueba la mejor ruta entre múltiples destinos en multihilos, mejorando la eficiencia. 31
El componente AstarPath [17][18] de este asset se agrega al GO A* del proyecto para seleccionar la superficie que engloba la escena y obtener su representación en nodos. En la ventana Scene de Unity de la Figura 26 se puede observar que, a través de pequeños cuadrados rojos, se distinguen las zonas caminables de las que no. Cuando el componente Seek del prefab Enemy se ejecuta, compara el nodo origen con todos los nodos caminables y se queda con la ruta de menor coste que lo lleva al destino. 32
Figura 26: Componente AstarPath del GO A* y el efecto de su ejecución sobre la superficie del grid, arriba y abajo, respectivamente. B. Pruebas Se realizan numerosas pruebas que permitan comprobar las mecánicas del juego y dar validez al prototipo. A continuación, se detalla qué pruebas se realizaron para cada 33
elemento que conforma el juego. B.1. Pruebas realizadas para validar la lógica de los soldados en formación Con los enemigos quietos se va atacando uno a uno y se comprueba que termina correctamente el juego, es decir, se eliminan a todos los enemigos. Con los enemigos quietos se ataca directamente al enemigo jefe que nos proporciona la victoria y se comprueba que tras su muerte termina el juego correctamente. Con los enemigos en Modo Dios y quietos se verifica que los soldados de la formación atacan únicamente cuando tienen un enemigo a la distancia permitida y en ausencia de obstáculos no atravesables. Se comprueba que los soldados de la formación no atacan, aunque se encuentre a distancia de ataque un enemigo, por la presencia de un obstáculo en medio. Con la formación en Modo Dios y quieta se constata que los enemigos matan a los soldados de la formación y el juego termina correctamente. Se confirma que los soldados se mueven exclusivamente por las zonas del mapa permitidas, sin atravesar obstáculos. Con el enemigo quieto se examina que se efectúan los cambios de la formación, es decir, se observa que la posición de los soldados cambia. Con el enemigo quieto y matando una fila de la formación se comprueba que el cam- bio de formación se realiza sin problemas. Lo mismo pero eliminando una columna. Con el enemigo quieto y matando enemigos aleatorios se comprueba que la forma- ción cambia correctamente. Además, se verifica aproximándose a los obstáculos y/o soldados enemigos que si están ocupadas por estos las posiciones futuras el cambio no se efectúa. B.2. Pruebas realizadas para validar la lógica de los soldados enemigos Con la formación en Modo Dios y quieta se comprueba que el enemigo ataca si al menos un soldado de la formación se encuentra a distancia de ataque y en ausencia de obstáculos no atravesables. Se comprueba que el enemigo no ataca, aunque se encuentre a distancia de ataque un soldado de la formación, por la presencia de un obstáculo en medio. Con la formación en Modo Dios y quieta se comprueba que en caso de dos o más soldados a distancia de ataque sigue los criterios estipulados. Es decir, ataca al soldado a menor distancia, si dos soldados a igual distancia se ataca al de menor vida y si tienen la misma vida se ataca al más fuerte. En caso de coincidencia en este último se elige aleatoriamente. Se comprueba el movimiento del mismo modo. 34
Se verifica que los obstáculos los evita y no los atraviesa a la hora de calcular el mejor camino. B.3. Pruebas realizadas para el ajuste de la latencia Se realiza a base del ajuste y desajuste de los umbrales inferior y superior que se aplican al pulso, hasta encontrar un punto de confort en el juego. C. Manual de usuario Al arrancar la aplicación, una vez que se carga el juego, en pantalla se observa a la formación en disposición 3x3 y a soldados enemigos esperando la oportunidad para atacar o moverse. En la Figura 27 se ilustra la pantalla inicial del primer nivel desarrollado, en la que aparecen los dos tipos de soldados y algunos elementos que forman el mapa. Para comprender la dinámica del juego se divide la explicación de este Anexo en dos partes. En el Anexo C.1 se presentan los elementos del primer nivel y en el Anexo C.2 se explica cómo empezar a jugar. Figura 27: Pantalla inicial al entrar al juego. C.1. Elementos del juego Los elementos que conforman el primer nivel del juego se presentan en la tabla de la Figura 28, indicando el nombre del elemento, su apariencia en el juego y sus características principales 35
También puede leer