Estudio y aplicación de un juego en red multijugador para dispositivos móviles
Abstract
Grado en Ingeniería Informática
Full text
Escuela de Ingeniería Informática de Valladolid Trabajo de Fin de Grado Grado en Ingeniería Informática Mención en Ingeniería del Software Estudio y aplicación de un juego en red multijugador para dispositivos móviles Presentado por: Carlos López Garcinuño Tutelado por: María Margarita Gonzalo Tasis
Resumen 2
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 3 Resumen El ocio digital se presenta actualmente como una gran potencia económica, laboral y social. El crecimiento que ha tenido este sector y lo que ha aportado tanto a la economía como a la sociedad para de sorprendernos. Según AEVI [1], la Asociación Española de Videojuegos, el mercado global del videojuego creció un 8,5% en el año 2016 con respecto al año anterior alcanzando una facturación total de 99.600 millones de dólares (más de 92.000 millones de euros). Teniendo en cuenta las posibilidades de este sector, más concretamente el mercado de los videojuegos en red, se presenta este TFG como representación del proceso de aplicación y aprendizaje de las herramientas necesarias para el desarrollo de un juego multijugador en red para dispositivos móviles, usando el motor de juegos Unity.
Resumen 4
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 5 Abstract Digital leisure is currently presented as a great economic, labor and social power. The growth that this sector has had and what it has contributed to both the economy and society do not stop surprising us. According to AEVI [1], the Spanish Association of Video Games, the global video game market grew by 8.5% in 2016 compared to the previous year, reaching a total turnover of $99.6 billion (more than 92 billion euros). Taking into account the potential of this sector, more specifically the market of the network video games, this bachelor theses is presented as a representation of the application process and learning the necessary tools for the development of a networked multiplayer game for mobile devices, using the Unity game engine.
Abstract 6
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 7 Índice de contenidos Resumen ........................................................................................................................................ 3 Abstract ......................................................................................................................................... 5 Índice de contenidos ..................................................................................................................... 7 Índice de figuras .......................................................................................................................... 11 Índice de tablas ........................................................................................................................... 15 1. Introducción ........................................................................................................................ 19 1.1. Motivaciones ............................................................................................................... 19 1.2. Objetivos ..................................................................................................................... 20 1.3. Organización de la memoria ....................................................................................... 20 2. Contexto .............................................................................................................................. 23 2.1. Breve historia de la red ............................................................................................... 23 2.2. Aplicaciones móviles en red ........................................................................................ 26 2.3. Videojuegos ................................................................................................................. 28 2.3.1. Videojuegos multijugador ................................................................................... 29 2.3.2. Categorías de los videojuegos multijugador ....................................................... 31 2.3.3. Videojuegos multijugador y e-sports .................................................................. 37 2.4. Motores de videojuegos.............................................................................................. 40 2.4.1. Unity .................................................................................................................... 40 2.4.2. Unreal Engine ...................................................................................................... 41 2.4.3. Elección del motor ............................................................................................... 41 2.4.4. Tecnologías complementarias ............................................................................. 42 3. Documento de Diseño del Juego ......................................................................................... 45 3.1. Título ........................................................................................................................... 45 3.2. Plataforma ................................................................................................................... 45 3.3. Sinopsis de jugabilidad y contenido ............................................................................ 45 3.4. Categoría ..................................................................................................................... 46 3.5. Licencia ........................................................................................................................ 46 3.6. Mecánica ..................................................................................................................... 46 3.6.1. Cámara ................................................................................................................ 46 3.6.2. Controles ............................................................................................................. 46 3.6.3. Puntuación .......................................................................................................... 46 3.6.4. Guardar/Cargar ................................................................................................... 46 3.6.5. HUD ..................................................................................................................... 47
Índice de contenidos 8 3.7. Estados del juego ........................................................................................................ 47 3.7.1. Pantalla de Identificación .................................................................................... 47 3.7.2. Menú principal .................................................................................................... 47 3.7.3. Personalizar ......................................................................................................... 47 3.7.4. Lobby ................................................................................................................... 47 3.7.5. Jugar .................................................................................................................... 47 3.8. Tecnología ................................................................................................................... 47 3.9. Público ......................................................................................................................... 48 4. Desarrollo del proyecto ....................................................................................................... 49 4.1. Gestión de Riesgos ...................................................................................................... 49 4.1.1. Riesgos encontrados ........................................................................................... 52 4.2. Roles y funciones de los recursos disponibles ............................................................ 61 4.3. Planificación del proyecto ........................................................................................... 62 4.3.1. Proceso de desarrollo .......................................................................................... 62 4.3.2. Fases del proyecto ............................................................................................... 63 4.3.3. Costes de producción previstos .......................................................................... 67 4.3.4. Seguimiento del proyecto ................................................................................... 68 5. Análisis ................................................................................................................................. 71 5.1. Propósito general ........................................................................................................ 71 5.2. Alcance del sistema ..................................................................................................... 71 5.3. Requisitos del sistema ................................................................................................. 71 5.3.1. Requisitos funcionales ......................................................................................... 72 5.3.2. Requisitos no funcionales ................................................................................... 74 5.3.3. Modelo de Casos de Uso ..................................................................................... 76 5.4. Flujo de actividad del jugador ..................................................................................... 91 6. Diseño .................................................................................................................................. 93 6.1. Modelo de dominio de Unity ...................................................................................... 93 6.1.1. Explicación del modelo de dominio de Unity ...................................................... 94 6.2. Modelo de dominio ..................................................................................................... 98 6.2.1. Clases del modelo de dominio ............................................................................ 99 6.3. Arquitectura lógica .................................................................................................... 102 6.4. Patrones de diseño .................................................................................................... 104 6.4.1. Patrones de diseño propuestos por Unity ........................................................ 104 6.4.2. Patrones de diseño elegidos para el proyecto .................................................. 105 6.5. Modelo relacional ..................................................................................................... 109
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 9 6.6. Diagramas de secuencia ............................................................................................ 109 6.6.1. Diagrama de secuencia de Player...................................................................... 110 6.6.2. Diagrama de secuencia de SkillshotProjectile ................................................... 112 7. Implementación ................................................................................................................ 113 7.1. Jugabilidad ................................................................................................................. 113 7.2. Prototipos .................................................................................................................. 115 7.3. Interfaz de usuario fuera de partida ......................................................................... 119 7.3.1. Personalización AbilitySet ................................................................................. 119 7.4. Interfaz de usuario dentro de la partida ................................................................... 123 7.4.1. Personaje ........................................................................................................... 123 7.4.2. HUD ................................................................................................................... 127 7.4.3. SkillshotProjectile .............................................................................................. 131 7.4.4. Items .................................................................................................................. 132 7.4.5. Animaciones ...................................................................................................... 133 7.4.6. Movimiento ....................................................................................................... 135 7.5. Gestión de las funcionalidades de red ...................................................................... 136 7.5.1. Atributos ............................................................................................................ 138 7.5.2. Variables de red................................................................................................. 140 7.5.3. Uso de atributos y funciones en el proyecto .................................................... 141 7.5.4. Otras cuestiones derivadas de la red ................................................................ 142 7.6. Base de Datos con SQLite .......................................................................................... 143 7.7. Recursos utilizados .................................................................................................... 144 7.7.1. Recursos adquiridos de la Asset Store de Unity ................................................ 145 7.7.2. Recursos adquiridos de distintos creadores ..................................................... 146 8. Pruebas .............................................................................................................................. 149 8.1. Pruebas unitarias ....................................................................................................... 149 8.1.1. Pruebas unitarias fuera de la partida ................................................................ 150 8.1.2. Pruebas unitarias dentro de la partida.............................................................. 156 8.2. Pruebas de integración ............................................................................................. 163 8.2.1. Prueba de integración en Personalizar ............................................................. 164 8.2.2. Prueba de integración en Lobby ....................................................................... 165 8.2.3. Prueba de integración en partida...................................................................... 166 9. Conclusiones...................................................................................................................... 167 9.1. Conclusiones generales ............................................................................................. 167 9.2. Futuras líneas de desarrollo ...................................................................................... 168 Bibliografía ................................................................................................................................ 170
Índice de tablas 16 Tabla 5.25. UC-003. Impactar habilidades .................................................................................. 80 Tabla 5.26. UC-004. Recoger objetos .......................................................................................... 81 Tabla 5.27. UC-005. Alterar atributos de los personajes ............................................................ 82 Tabla 5.28. UC-006. Revertir atributos de los personajes ........................................................... 83 Tabla 5.29. UC-007. Identificarse ................................................................................................ 84 Tabla 5.30. UC-008. Seleccionar kit de habilidades .................................................................... 85 Tabla 5.31. UC-009. Personalizar kit de habilidades ................................................................... 86 Tabla 5.32. UC-010. Crear partida ............................................................................................... 87 Tabla 5.33. UC-011. Descubrir partidas creadas ......................................................................... 87 Tabla 5.34. UC-012. Unirse a partida creada .............................................................................. 88 Tabla 5.35. UC-013. Pulsar el botón de “preparado” .................................................................. 89 Tabla 5.36. UC-014. Iniciar partida .............................................................................................. 90 Tabla 5.37. UC-015. Finalizar partida .......................................................................................... 90 Tabla 8.1. PCN-001. Identificación correcta sin usuario creado previamente .......................... 150 Tabla 8.2. PCN-002. Identificación correcta con usuario creado previamente ........................ 150 Tabla 8.3. PCN-003. Entrar correctamente al menú de Personalizar ....................................... 151 Tabla 8.4. PCN-004. Seleccionar un AbilitySet como favorito ................................................... 151 Tabla 8.5. PCN-005. Entrar a editar un AbilitySet ..................................................................... 151 Tabla 8.6. PCN-006. Seleccionar una Skillshot .......................................................................... 152 Tabla 8.7. Seleccionar una Pasiva .............................................................................................. 152 Tabla 8.8. PCN-008. Cambiar Skillshot/Pasiva del AbilitySet por la seleccionada .................... 152 Tabla 8.9. PCN-009. Cambiar el nombre del AbilitySet ............................................................. 153 Tabla 8.10. PCN-010. Guardar toda la información cambiada .................................................. 153 Tabla 8.11. PCN-011. Guardar toda la información cambiada .................................................. 153 Tabla 8.12. PCN-012. Salir sin guardar ...................................................................................... 154 Tabla 8.13. PCN-013. Pulsar el botón de Jugar ......................................................................... 154 Tabla 8.14. PCN-014. Crear partida ........................................................................................... 154 Tabla 8.15. PCN-015. Buscar partidas creada ........................................................................... 155 Tabla 8.16. PCN-016. Unirse a una partida ............................................................................... 155 Tabla 8.17. PCN-017. Personalizar el color y el nombre antes de la partida ............................ 155 Tabla 8.18. PCN-018. Pulsar el botón de "Preparado" e inicia la partida ................................. 156 Tabla 8.19. PCN-019. La partida empieza para el Player .......................................................... 156 Tabla 8.20. PCN-020. La partida empieza para el Player .......................................................... 157 Tabla 8.21. PCN-021. El HUD se mantiene actualizado en todo momento .............................. 157 Tabla 8.22. PCN-022. El usuario mueve al Player con el Joystick .............................................. 157 Tabla 8.23. PCN-023. Lanzar Skillshot ....................................................................................... 158 Tabla 8.24. PCN-024. Lanzar Skillshot ....................................................................................... 158 Tabla 8.25. PCN-025. Recoger objeto ....................................................................................... 158 Tabla 8.26. PCN-026. El Player ve afectadas sus estadísticas al recoger un objeto .................. 159 Tabla 8.27. PCN-027. Se revierten los efectos aplicados por un PlayerModifier ...................... 159 Tabla 8.28. PCN-028. Muerte de un Player ............................................................................... 159 Tabla 8.29. PCN-029. La partida llega al tiempo límite ............................................................. 160 Tabla 8.30. PCN-030. Correcto funcionamiento de las posiciones de los jugadores en red ..... 160 Tabla 8.31. PCN-031. Correcto funcionamiento de las Skillshot en red ................................... 160 Tabla 8.32. PCN-032. Correcto funcionamiento de las Skillshot en red ................................... 161 Tabla 8.33. PCN-033. Correcto funcionamiento de la recogida de objetos en red .................. 161
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 17 Tabla 8.34. PCN-034. Muerte de otro Player ............................................................................ 161 Tabla 8.35. PCN-035. Muerte de otro Player ............................................................................ 162 Tabla 8.36. PCN-036. Player impactado por una Skillshot ........................................................ 162 Tabla 8.37. PCN-037. Player impactado por una Skillshot ........................................................ 163 Tabla 8.38. PI-001. Prueba de integración de los menús de personalizar ................................ 164 Tabla 8.39. PI-002. Prueba de integración para el creador de la partida ................................. 165 Tabla 8.40. PI-003. Prueba de integración para unirse a una partida ....................................... 165 Tabla 8.41. PI-004. Prueba de integración en partida ............................................................... 166
Índice de tablas 18
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 19 1. Introducción En este capítulo realizaremos una breve introducción del contenido de la memoria y el proyecto que ésta representa. Hablaremos sobre las motivaciones de la elección de dicho trabajo y los objetivos a cumplir. 1.1. Motivaciones A lo largo de la historia reciente, la tecnología, con el afán de descubrir y de reinventarse, ha proporcionado a la humanidad diferentes y renovadas formas de realizar sus acciones cotidianas. Muchos de estos avances han sido orientados a la productividad, la organización y la eficiencia. Sin embargo, el ocio también ha sido uno de los aspectos más beneficiados por esta evolución. Con el surgimiento de los videojuegos, el ocio para la gente tuvo un nuevo abanico de oportunidades abierto ante ellos. Seguían teniendo limitaciones, ya que para poder jugar con sus amigos tenían que seguir juntándose físicamente. Pero, al poco tiempo, la introducción de la red en los videojuegos proporcionó la posibilidad de jugar con amigos desde casa. La tecnología había acabado con esa limitación. Considerando el potencial que poseen hoy día los videojuegos en red como herramienta para divertir y unir a la gente, hemos decidido enfocar este proyecto en la realización de un juego multijugador en red, para dispositivos móviles y poder explorar las posibilidades y resolver los problemas que éstos nos presentan.
Introducción 20 1.2. Objetivos En cuanto a los objetivos que queremos perseguir con la realización de este proyecto, hemos planteado los siguientes. • Comprender el proceso de desarrollo de un juego desde cero. • Adaptar los conocimientos adquiridos de Ingeniería del Software aprendidos en la carrera en el desarrollo del proyecto. • Aplicar conceptos de gestión de proyectos y toma de decisiones. • Aprender a utilizar de manera correcta todas las herramientas que nos brinda el motor del videojuego, así como el lenguaje de programación C#. • Observar y analizar videojuegos similares al planteado con el objetivo de ayudar a resolver, como hacen ellos, ciertos problemas relacionados con la plataforma y con el tipo de juego en concreto. • Aprender y aplicar el funcionamiento de la red en los videojuegos, consiguiendo así un videojuego con una buena jugabilidad para varios usuarios simultáneos. • Aprender la gestión dentro del juego de los elementos que caracterizan a los juegos tipo MOBA y sus mecánicas. • Estudiar cómo permitir jugar a los usuarios juntos en cada partida y construir una solución. 1.3. Organización de la memoria A lo largo de este documento abordaremos todos los aspectos relativos al proyecto. Con el objetivo de situar al lector, se procede a hacer una breve descripción del contenido de cada capítulo. • Capítulo 1: Introducción. Se presentan los objetivos y motivaciones del proyecto. • Capítulo 2: Contexto. Se sitúa el proyecto en el contexto histórico, técnico y teórico. • Capítulo 3: Documento de Diseño del Juego. Se describen las principales características específicas del videojuego. • Capítulo 4: Desarrollo del Proyecto. Se presenta la metodología de desarrollo que se seguirá, así como la gestión de riesgos y la planificación. • Capítulo 5: Análisis. Se detallan los requisitos y casos de uso del sistema.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 21 • Capítulo 6: Diseño. Se describen y presentan los modelos de dominio pertinentes. Diagramas y patrones relativos al diseño de la aplicación. • Capítulo 7: Implementación. Se explican los elementos relevantes de la implementación de la aplicación. • Capítulo 8: Pruebas. Se presentan las pruebas a las que ha sido sometido el software y el resultado de ellas. • Capítulo 9: Manuales. Se muestran los manuales de instalación y uso de la aplicación. • Capítulo 10: Conclusiones. Valoraciones finales del proyecto, evaluación de la consecución de los objetivos marcados y posibles mejoras para el futuro de la aplicación.
Introducción 22
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 23 2. Contexto 2.1. Breve historia de la red Hace algo más de 20 años, las computadoras eran una novedad para la mayoría. Proporcionaban, al mismo tiempo, el mismo servicio que una máquina de escribir, una calculadora y un centro de entretenimiento, todo en un solo aparato. Las redes de computadoras eran algo completamente extraño para el usuario medio. La principal forma de compartir información de una máquina a otra era el disquete. El gobierno de los Estados Unidos se dio cuenta de la importancia y potencial de la tecnología de internet y promovió una investigación que hizo posible un internet global. La tecnología DARPA incluía un conjunto de estándares de red que especificaban en detalle cómo los ordenadores debían comunicarse, así como convenciones para interconectar redes y el reenvío de tráfico. Oficialmente se llamó TCP/IP Internet Protocol Suite (Conjunto de protocolos de Internet) pero al final se quedó con TCP/IP [2] [3] [4], que son el nombre de sus dos estándares más principales e importantes. TCP significa Protocolo de control de transmisión, e IP, Protocolo de internet. Pasó a ser el estándar a nivel mundial para la interconexión de sistemas. No hay ningún otro protocolo que ofrezca tanta interoperabilidad ni se ejecuta sobre tantas tecnologías de red como TCP/IP. Uno de los protocolos que más nos va a interesar en las cuestiones que vamos a tratar, por la importancia que tiene en un campo como es el de los videojuegos, es el UDP. Este se utilizaba incluso antes del nacimiento de TCP, pero debido a la necesidad de la fiabilidad que UDP no podía garantizar, TCP tomó mucha importancia.
Contexto 24 El Protocolo de Datagramas de Usuario [5] [6], o UDP (User Datagram Protocol) es un protocolo del nivel de transporte (al igual que TCP). La diferencia fundamental entre UDP y TCP es que UDP no proporciona obligatoriamente transmisiones de datos fiables. Es más, el protocolo no garantiza que los paquetes finalmente lleguen a su destino, como sí hace TCP. Aunque pueda parecer extraño, esto es útil para una serie de tareas. Tareas que requieren transmitir la máxima información en el menor tiempo posible, sin problemas de fiabilidad. Por ejemplo, en las aplicaciones de streaming de video en directo, es más importante que la imagen y el sonido lleguen sin mucho retardo a que se vea totalmente completa y a máxima resolución (llegarían el 100% de los paquetes). También es el caso de los videojuegos multijugador online en tiempo real. Es más importante y necesario para una buena experiencia de juego que las acciones de los usuarios lleguen lo antes posible al servidor, a que lleguen todos y cada uno de los paquetes. Aunque la gran mayoría de servicios van a necesitar el protocolo TCP porque realmente sí necesitan que todos y cada uno de los paquetes lleguen a su destino, la función que cumple UDP es algo que TCP no puede igualar. Muchos programas utilizan conexiones separadas TCP y UDP. La información importante se envía a través de una conexión TCP fiable, mientras que el flujo principal de datos se envía por UDP. La explicación de por qué UDP es más rápido que TCP es la siguiente: el cometido de TCP es proporcionar transmisiones de datos fiables y mantener una conexión entre dispositivos o servicios que estén “manteniendo una conversación”. De este modo, si se recibe algún paquete corrupto, no se recibe, o llega en un orden incorrecto, TCP es el encargado de la recuperación de los datos. Para ello, utiliza una confirmación (ACK) de la máquina de destino, que es enviada una vez se hayan recibido correctamente los datos. UDP, al evitar todo esto, es claramente más rápido y eficiente para los casos mencionados anteriormente. Otro motivo por el que es más rápido es que el paquete es mucho más ligero. Aquí tenemos el paquete de TCP.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 25 Figura 2.1. Cabecera TCP Fuente: [7] Y aquí el de UDP, con muchos menos bits ocupados. Lo que le permite ser más pequeño, sin impedirle enviar la información realmente importante. Figura 2.2. Cabecera UDP Fuente: [8] Gracias a estos protocolos, la situación fue cambiando y las redes de computadores empezaron a llenar las aulas y oficinas. El correo electrónico nos permitió comunicarnos de forma global de manera instantánea. Ya no era necesario desplazar la información manualmente de un sitio a otro. Simplemente bastaba con conectarse con un módem y una línea telefónica y hacer las transacciones. Al dotar a las máquinas de capacidad para comunicarse entre sí, se permitió que la información fluyera, así nació la red de computadoras. Tras esto, internet no hizo más que evolucionar, las líneas telefónicas y los módems dieron paso a las líneas de ADSL, fibra óptica e incluso se incorporó a los teléfonos móviles. Actualmente estamos en esta fase de la tecnología, los smartphones son uno de los principales focos en los que se centra la innovación, y como éstos, las aplicaciones que pueden ejecutar.
Contexto 32 2.3.2.2.2. Disparos en tercera persona (TPS – Third Person Shooter) Muy similares en cuanto a mecánicas de los FPS pero con la diferencia de que la cámara se encuentra en tercera persona. Suele ser útil para juegos en los que el objetivo no es solo disparar, sino que, por ejemplo, el jugador debe recoger objetos del suelo y por ello es necesario tener más conocimiento espacial. Figura 2.9. Jugador recogiendo objetos del suelo en Fortnite Fuente: [20] Dos juegos muy populares en esta categoría que realmente han tenido un gran éxito en estos últimos años son PlayerUnknown's Battlegrounds (PUBG) y Fortnite, ambos con versión para smartphone. 2.3.2.3. Estrategia Este tipo de juegos requieren que el jugador ponga en práctica sus habilidades de planeamiento e inteligencia para maniobrar, gestionando recursos de diverso tipo (materiales, humanos, militares...) para conseguir la victoria. La mayoría son de temática bélica, pero los hay también centrados en estrategia económica o empresarial. 2.3.2.3.1. Estrategia en tiempo real (RTS – Real Time Stategy) Dentro de la estrategia en tiempo real, podemos distinguir dos. El primero lo conformarían juegos como el Imperivm, Warcraft, StarCraft, etc. La principal diferencia con el segundo grupo es que éstos se juegan en una serie
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 33 de mapas, para una partida en concreto. Y una vez acabada la partida ese mapa desaparece, como pasa con los mapas mencionados en Counter Strike. Son mapas de “usar y tirar”, las partidas pueden durar horas, pero no mucho más. Figura 2.10. Imperivm Fuente: [21] En el segundo grupo (MMORTS) tendríamos juegos como OGame y Clash Of Clans. Como decíamos, a diferencia del primer grupo, el mapa no es de “usar y tirar”, sino que en éste, las unidades, las estructuras y los recursos, se mantienen, en un mundo persistente que evoluciona independientemente de que los jugadores estén conectados o no. Este tipo de juegos triunfaron mucho como juegos de navegador. 2.3.2.3.2. Estrategia por turnos (TBS – Turn Based Stretegy) Este tipo de juegos, entre los que se encuentran los Civilization y la saga Total War, se caracterizan por dividir el flujo del juego en varias partes bien definidas llamadas turnos o rondas. En el caso de estos dos juegos mencionados, el juego se suele desarrollar en un mapa del territorio en el que vas organizando tus ejércitos, planteando políticas y atacando o defendiendo otros territorios. Al final de tu turno, el rival (o rivales) realiza las mismas acciones hasta que te vuelve a ceder el turno. Estos juegos a menudo incorporan la posibilidad de manejar ciertas batallas como si de un RTS se tratara.
Contexto 34 Figura 2.11. Medieval II - Total War Fuente: [22] 2.3.2.4. Deporte Esta categoría se centra en videojuegos sacados de deportes reales llevados al terreno virtual. Se encuentran juegos como el FIFA, el Pro Evolution Soccer, NBA. Todos estos juegos tienen una gran fanbase y mucha gente que juega al modo multijugador, sobre todo, destaca el FIFA, que posee un modo multijugador online en el que puedes crear tu equipo de fútbol y competir en una liga con jugadores de todo el mundo. 2.3.2.5. Carreras En cuanto a los videojuegos de carreras, mucha similitud con la sección anterior. Carreras, generalmente de coches, simuladas en el juego. Estas simulaciones pueden ir desde las más realistas, como por ejemplo Fórmula 1 o Gran Turismo, pasando por algo más fantástico como Need For Speed, hasta llegar a Mario Kart, inspirado en el universo de Nintendo. 2.3.2.6. Aventura Son videojuegos habitualmente basados en una trama en la que el usuario va avanzando, interactuando con personajes y resolviendo las situaciones que van apareciendo. Este género dedica la mayoría de sus títulos a un solo jugador, dando mucha importancia al modo historia, como pueden ser The Last Of Us, Uncharted y God Of War.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 35 Sin embargo, hay alguno que sí incorpora algún tipo de modo multijugador, como puede ser Left 4 Dead y Assassins Creed. 2.3.2.7. Rol Aunque pueden enmarcarse en la sección de Aventuras, el género de juegos de rol (RPG) tiene tantos títulos y éxito que ha pasado a ser un género propio, como ocurre con los Shooter. Tienen todo lo que tiene un juego de aventuras (personajes y trama) pero hay un desarrollo del personaje en el que va adquiriendo armas, habilidades nuevas o aliados. Ejemplos de estos juegos podrían ser Skyrim, Dungeons & Dragons o incluso Pokémon. Los juegos nombrados no son online, o, al menos, en su primer diseño. Para ir al terreno online, tenemos que hablar de los MMORPG (massively multiplayer online role-playing game). Como su nombre indica, se trata de juegos multijugador online masivos, lo que significa que pueden albergar a miles y miles de jugadores de forma simultánea en un mundo permanente, que nunca duerme. Figura 2.12. Expansiones de las que dispone World of Warcraft Fuente: [23] El título más conocido de esta categoría es el World Of Warcraft [24], lanzado en 2004, fue todo un éxito aclamado por la crítica. Desde que se lanzó, hasta el día de hoy, ha sacado un total de seis expansiones para ir renovándose y mantener a los fans, sin que estos pierdan el interés. 2.3.2.8. MOBA MOBA (Multiplayer Online Battle Arena), considerado un subgénero dentro de los juegos de estrategia, y más concretamente en los de estrategia de acción en tiempo real (ARTS), hablaremos de él como de un género más debido, sobre todo, al gran auge que ha tenido este tipo de juegos tanto en número de jugadores como en su importancia dentro de los e-sports. La diferencia en cuanto a un juego de estrategia tradicional es que solamente manejas un personaje, el cual suele tener habilidades especiales y que pelea, generalmente contra otro equipo en igualdad numérica, al lado de otros
Contexto 36 compañeros. En la mayoría, el objetivo del juego es destruir la base enemiga, aunque hay alguno en que simplemente es acabar con el equipo enemigo. También suele haber unidades más pequeñas manejadas por el juego que ayudan a los jugadores, comúnmente llamados “súbditos”, aunque no todos los tienen. En cuanto al origen de este género, nos remontamos a la aparición de un mapa personalizado para StarCraft, llamado Aeon of Strife, en el cual cada jugador manejaba a una unidad más poderosa que el resto y la máquina manejaba al resto. Después de esto, vino DotA, un mapa basado en lo mencionado anteriormente pero para otro juego, Warcraft III: Reign of Chaos, este es considerado el primer MOBA del que se empezaron a realizar torneos de los seguidores. A raíz del éxito de este novedoso estilo de juego se crearon otros, entre los que destaca League Of Legends y Dota 2. Figura 2.13. Partida retransmitida en directo de League Of Legends Fuente: [25] League Of Legends [26] se lanzó en 2009 y su dinámica principal es destruir la base enemiga. Para llegar a ella se destruyen tanto los súbditos, como torres o, los enemigos manejados por otros jugadores que nos vayamos encontrando. Dentro del juego hay distintos roles, y aunque no vamos a profundizar en ellos, nos parece relevante mencionar que para que un equipo esté balanceado debe haber personajes muy duros y lentos y otros muy ligeros y rápidos. Cada personaje tiene sus habilidades únicas que lo diferencian de los demás, y le ayudan a combatir a sus adversarios y/o ayudar a sus aliados.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 37 Por el componente inherentemente competitivo que tiene este tipo de juegos, a menudo, 5 vs 5, y gana uno, como si de un partido de fútbol se tratase, ha llegado a ser el mayor referente dentro de los e-sports, elevando este fenómeno a unos niveles insospechados hace unos años. 2.3.3. Videojuegos multijugador y e-sports Los deportes electrónicos o e-sports son competiciones de videojuegos multijugador en los que se enfrentan jugadores profesionales. Los géneros más comunes, y también, los más populares. Estos son: estrategia en tiempo real (StarCraft II), disparos en primera persona (Counter Strike: GS) y MOBA (League Of Legends y Dota 2). Los e-sports [27] existen desde hace bastante tiempo, pues empezaron prácticamente con los juegos multijugador. El componente del reto entre los jugadores es un elemento que, tarde o temprano desembocaría en torneos. Al principio se trataba de competiciones locales, pero con la expansión de internet y las mejoras tanto en los ordenadores como en la calidad de los juegos, estos torneos fueron cada vez más grandes, llegando así a más gente. A partir del año 2012 aproximadamente, hubo un juego que empezó a sobrepasar todos los récords en cuanto a seguimiento y visualizaciones, el mencionado League Of Legends. Algunos informes reflejan que en 2011 contaba con 11.5 millones de usuarios, en 2014 ya eran 67, y en 2016 llegó a los 100, siendo la última cifra conocida, aunque viendo la proyección no extrañaría que los hubiera superado ampliamente. El mayor evento de este videojuego es el mundial (League Of Legends World Championship), en el cual, se reúnen los mejores equipos de las distintas regiones participantes (Corea, China, Europa, Norte América, etc).
Contexto 38 Figura 2.14. Estadio de las finales de los Worlds de League of Legends Fuente: [28] Este evento, en 2017, [29] pudo congregar a 80 millones de espectadores únicos en la semifinal (en la que se enfrentaban los dos favoritos) y a 56 millones en la final. Podemos decir así que este juego, junto con otros no tan ampliamente seguidos, pero sí muy populares, han creado una industria que ha venido para quedarse, los e-sports. Tanto es así que, visto el éxito, muchas productoras de videojuegos se están esforzando por intentar enfocar sus juegos en un tono más competitivo, por si tuvieran la suerte de que algún día esos juegos también llegaran a ser un deporte electrónico. Puede parecer que los e-sports se limitan a juegos de ordenador, pero no es así. Aunque la gran mayoría son para PC, últimamente salen nuevos e-sports muy seguidos en otras plataformas, como son los dispositivos móviles. Es el caso de Clash Royale.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 39 Figura 2.15. Partida de Clash Royale Creado por Supercell, es un juego que mezcla varios géneros, entre ellos cartas coleccionables, defender la torre y estrategia en tiempo real. Sus plataformas son móviles y tabletas, siendo un juego que se juega de manera táctil, indicando con el dedo dónde quieres desplegar las unidades. El objetivo es tirar más torres al final de la partida o acabar con la torre central de tu rival antes que él. Mecánica sencilla, pero con muchos detalles y unidades (cartas) muy variadas. Esta empresa se ha animado recientemente (diciembre 2018) a lanzar su propio MOBA, Brawl Stars. No es un MOBA tan complejo como League Of Legends, los juegos de móviles tienen sus particularidades y problemática concreta, al igual que tienen sus puntos a favor. Debido a las limitaciones que tiene la pantalla, hay que aprovechar muy bien el espacio disponible para que el jugador pueda manejarse libremente, sin que le quiten mucha visibilidad sus propios dedos. Otra cosa para tener en cuenta son los gráficos y si el juego es 2D o 3D, ya que los móviles no tienen la misma capacidad de procesamiento que un PC. En cuanto a los pros, tenemos la gran accesibilidad al juego, ya que cualquier usuario lo puede encontrar en la tienda de su smartphone y, si el juego no requiere mucho, podrá ser jugado en prácticamente cualquier dispositivo. Otro punto importante es la inmediatez. Simplemente pulsar el icono del juego en tu smartphone para empezar a jugar, en cambio, los juegos de PC no son tan inmediatamente accesibles.
Contexto 40 Podemos concluir que la sencillez y accesibilidad es la clave para conquistar los e-sports en los smartphones. 2.4. Motores de videojuegos Para ayudar a los desarrolladores a realizar los videojuegos, se dispone de unas herramientas específicas llamadas motores de videojuegos (game engine). Estos entornos de desarrollo proveen herramientas que se centran en los aspectos más característicos de los videojuegos, aspectos que otro tipo de software no necesita. Entre estas funcionalidades podemos encontrar: • Renderizado de gráficos 2D y 3D, una de las más importantes ya que sin ella no podríamos ver correctamente el videojuego. • Librerías de simulación de fuerzas físicas, que imite, en caso de que se quiera, las leyes de la física. También sirven, por ejemplo, para detectar colisiones entre elementos. • Animación, tanto en 2D como en 3D, que permite que cualquier elemento del entorno del videojuego sea animado, ayudado por los renderizadores. • Scripting, permite que los elementos del videojuego, creados con el editor, como pueden ser figuras o personajes, tengan un comportamiento específico designado por un script. • Sonidos, permite incluir sonidos para que el videojuego los reproduzca en momentos determinados. A parte de las mencionadas, según el motor gráfico que escojamos, se nos puede proporcionar otros aspectos que también pueden ser útiles, como inteligencia artificial o el uso de redes. A continuación, vamos a ver un poco de los más importantes. 2.4.1. Unity Unity [30] [31] es un motor de videojuego multiplataforma desarrollado por Unity Technologies. Es una de las opciones más recomendadas para principiantes, debido a que la curva de aprendizaje es moderada, además de que hay una comunidad amplia que puede ayudar a resolver las dudas. Se recomienda para hacer juegos relativamente sencillos para múltiples plataformas.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 41 Figura 2.16. Logo de Unity 2.4.2. Unreal Engine Unreal Engine es un motor de videojuego desarrollado por Epic Games. Es una herramienta usada hoy día por un gran número de desarrolladores de juegos. Actualmente en su versión 4, está considerado el motor más potente del mercado, permitiendo crear juegos con un nivel de realismo muy elevado. La curva de aprendizaje es más complicada y la comunidad no es tan grande como la de Unity. Figura 2.17. Logo de Unreal Engine 2.4.3. Elección del motor Hay muchos más motores gráficos, pero los dos más importantes y con más comunidad, son los indicados. Así que vamos a hacer una comparativa para ver cuál es el que más se ajusta al proyecto [32]. Como hemos mencionado anteriormente, unas de las mejores bazas de Unity es su curva de aprendizaje y la comunidad que posee, la cual hace aún más asequible el aprendizaje. Unreal Engine en cambio tiene una curva algo más difícil, y la comunidad no es tan amplia como la de Unity. En cuanto al tema de la potencia, Unreal es bastante más potente que Unity, permite hacer juegos más complejos y conseguir unos resultados muy realistas. Unity, en cambio, está orientado a juegos más sencillos. Esto es debido a que la potencia de Unreal, depende del rendimiento del dispositivo que lo va a ejecutar. Como en nuestro caso va a ser un juego sencillo, en 2D, y para móvil (rendimiento del dispositivo limitado), en este sentido, Unity es el más acertado.
Documento de Diseño del Juego 48 3.9. Público El juego va orientado a jóvenes de edades comprendidas entre 13-25 años. Que dispongan de smartphones y tarifa de datos o wifi para poder jugar con sus amigos.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 49 4. Desarrollo del proyecto En este capítulo se habla sobre el desarrollo del proyecto y todos sus aspectos. Hablaremos del proceso de software elegido para llevar a cabo el proyecto, la planificación, así como los riesgos a los que nos podemos enfrentar. • Documento de Gestión de Riesgos, en el que se detallan los riesgos que hemos podido encontrar en el inicio del proyecto, así como intentar prever los que puedan surgir a lo largo del desarrollo de este. • Planificación del proyecto, en el que se expone el proceso de desarrollo elegido, características y motivos de la decisión. Se realiza la subdivisión de las tareas del proyecto y la planificación en el tiempo de ellas. Por último, el seguimiento del trabajo y la planificación final. 4.1. Gestión de Riesgos A la hora de planificar un proyecto [35] [36], hay que tomar ciertas decisiones. En un escenario ideal, contaríamos con toda la información necesaria para poder tomarlas y sabríamos a ciencia cierta cuál sería el resultado de hacerlo. Desgraciadamente el mundo real no es así, y la mayoría de las decisiones que se pueden tomar, están basadas en información incompleta. La falta de información y la incertidumbre nos lleva a los riesgos, que son una parte inherente e intrínseca de la gestión de proyectos. Cada vez que queramos añadir algo que, aunque sea una gran idea, sumará peso al proyecto, habrá riesgos asociados a ello. Riesgos que, de no ser tenidos en cuenta y producirse, pueden hacer peligrar el proyecto.
Desarrollo del proyecto 50 La Gestión de Riesgos de Proyecto es definida por el PMBOK como: ‘… el proceso sistemático de identificar, analizar y reaccionar a los riesgos del proyecto… [durante todo el ciclo de vida del proyecto]. También define un riesgo como: ‘… factores que pueden causar un fracaso para cumplir los objetivos del proyecto…’. Una parte importante de la gestión de riesgos considerar qué probabilidad y qué impacto tendrá cada uno, para poder diseñar y priorizar los planes de mitigación y contingencia en consecuencia. Probabilidad de ocurrencia del escenario Muy baja Baja Media Alta Muy alta Impacto en el proyecto Muy bajo 0 1 2 3 4 Bajo 1 2 3 4 5 Medio 2 3 4 5 6 Alto 3 4 5 6 7 Muy alto 4 5 6 7 8 Tabla 4.1. Tabla de colores según impacto y probabilidad de riesgo Describimos a continuación los atributos que tendrá cada uno de los riesgos que encontremos. • Categoría: La categoría en la que se ve enmarcado el riesgo, puede ser de proyecto, de proceso o de producto. • Riesgos de Proyecto Restricciones de recursos, problemas de coordinación interna del equipo o del grupo, financiación no adecuada.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 51 • Riesgos de Proceso Proceso software pobremente documentado, no prevención de defectos, proceso de diseño insuficiente, gestión escasa de requisitos, planificación ineficaz. • Riesgos de Producto Falta de experiencia en el dominio de la materia, diseño demasiado complejo, interfaces definidas deficientemente, requisitos vagos o incompletos. • Probabilidad: Probabilidad de que ese riesgo ocurra, teniendo en cuenta el entorno y los distintos factores a los que se pueda exponer el proyecto. Según la probabilidad, podemos distinguirlo en: Muy alta: Más de 80% de probabilidades de que ocurra. Alta: Entre 60% y 80% de probabilidades de que ocurra. Media: Entre 40% y 60% de probabilidades de que ocurra. Baja: Entre 20% y 40% de probabilidades de que ocurra. Muy baja: Menos de 20% de probabilidades de que ocurra. • Impacto: El impacto que tendría en el proyecto el riesgo en caso de producirse. Puede ir desde un impacto prácticamente despreciable a uno crítico o incluso catastrófico. El impacto que suele tener un riesgo se ve afectado a nivel de costes y a nivel de planificación. Según el nivel de impacto podemos distinguirlo en: Muy alto: Más de 20% de sobrecostes sobre la planificación y estimación inicial. Alta: Entre un 15% y un 20% de sobrecostes sobre la planificación y estimación inicial. Media: Entre 10% y 15% de sobrecostes sobre la planificación y estimación inicial. Baja: Entre 5% y 10% de sobrecostes sobre la planificación y estimación inicial. Muy baja: Menos de 5% de sobrecostes sobre la planificación y estimación inicial. • Descripción:
Desarrollo del proyecto 52 Breve, pero precisa descripción del riesgo que se ha descubierto. • Fases afectadas: Las fases del proceso unificado que pueden ser afectadas por el riesgo, desde iniciación hasta transición. • Estrategia: Cómo afrontar el riesgo: podemos intentar evitarlo, podemos intentar protegernos de ello, podemos investigarlo o, incluso aceptarlo. • Plan de mitigación: Las estrategias del plan de mitigación [37] tratan de reducir la probabilidad de ocurrencia del riesgo, o bien, reducir el impacto que pueda causar. Están referidas al conjunto de acciones que se toman por adelantado o acciones proactivas. Es decir, las medidas para intentar que el riesgo finalmente no ocurra. • Plan de contingencia: El PMBOK define estrategias del plan de contingencia a aquellas respuestas que se utilizan solamente si ocurre el riesgo. Planes alternativos para que, en caso de que el riesgo finalmente ocurra, afecte en lo mínimo posible la planificación inicial del proyecto. Estos dos planes no son excluyentes. De hecho, es necesario planificar tanto el cómo intentar mitigar la posible ocurrencia de un riesgo como, en el caso de que éste finalmente ocurra, cómo poder corregirlo de la mejor forma posible y que afecte en la menor medida la planificación inicial del proyecto. 4.1.1. Riesgos encontrados La identificación de los riesgos es probablemente la parte más difícil e importante del proceso de gestión de riesgos. Si no eres capaz de identificar un riesgo, va a ser excluido, y por tanto no sometido a un análisis más detallado, por lo que probablemente, de producirse, no se estaría preparado para responder a él. Una de las mayores fuentes de información para la detección de riesgos es la experiencia.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 53 Al ser este el primer proyecto realizado en el motor gráfico Unity y con varias tecnologías cuyo funcionamiento se irá, o bien descubriendo de cero o bien profundizando más en una materia en la que se está solo iniciado, la experiencia es prácticamente nula y no podemos saber a qué riesgos específicos se enfrenta el proyecto. Lo que sí podemos saber es que esta falta de experiencia es un riesgo en sí mismo. Así que consideraremos como riesgos la falta de experiencia y los problemas que pueda acarrear ésta para el desarrollo del proyecto. RIE-001 Problemas de implementación de Unity Categoría Producto 5 Probabilidad Media Impacto Alto Descripción Debido a la inexperiencia con el motor Unity, podrían darse problemas de implementación y no cumplirse los objetivos relativos a experiencia de juego que se deseaban en un principio. Fases afectadas Construcción Gestión de riesgo Estrategia Formación e investigación en las herramientas de Unity y en las características concretas que se desean implementar. Plan de mitigación Realización de tutoriales específicos de esas características para intentar dominar las técnicas de implementación necesarias. Plan de contingencia Búsqueda de otra forma de implementar esas características, con otras técnicas, para que se parezcan lo más posible a lo ideal. Tabla 4.2. RIE-001. Problemas de implementación de Unity
Desarrollo del proyecto 54 RIE-002 Cambios en los requisitos Categoría Proceso 4 Probabilidad Media Impacto Medio/Alto Descripción Durante todo el proceso de desarrollo pueden darse cambios en los requisitos iniciales. A más tarde se decidan cambiar los requisitos, más alto será el impacto en el proyecto. Fases afectadas -Elaboración -Construcción Gestión de riesgo Estrategia Protegernos del riesgo Plan de mitigación Enfoque en las fases más iniciales en delimitar bien los requisitos y que, de haber cambios, sean menores y sin mucha importancia. Plan de contingencia Realización de las modificaciones tanto en la planificación como en la implementación para ajustar estos a los nuevos cambios. Tabla 4.3. RIE-002. Cambios en los requisitos
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 55 RIE-003 Errores o contenido ambiguo del diseño Categoría Proceso 3 Probabilidad Baja Impacto Medio Descripción Que los documentos de diseño finales no sean lo suficientemente concretos y descriptivos, puede llevar a errores en la implementación final. Fases afectadas -Elaboración -Construcción Gestión de riesgo Estrategia Protegernos del riesgo Plan de mitigación Enfocarse en tener algo muy concreto en los documentos de diseño y, en las propias etapas de Construcción, ir concretando más y más a medida que avanza el proyecto. Plan de contingencia Replantear ciertas bases del documento de diseño en la fase de Elaboración para darle un nuevo enfoque, intentando evitar lo que se ha diagnosticado que ha dado problemas en primera instancia. Tabla 4.4. RIE-003. Errores o contenido ambiguo del diseño
Desarrollo del proyecto 56 RIE-004 Indisponibilidad del desarrollador Categoría Proyecto 2 Probabilidad Baja Impacto Bajo Descripción Cabe la posibilidad de que el desarrollador caiga enfermo y éste no pueda realizar su actividad habitual durante varios días, lo que puede suponer algún retraso en la planificación. Fases afectadas -Elaboración -Construcción -Transición Gestión de riesgo Estrategia Aceptar el riesgo Plan de mitigación Plan de contingencia Dependiendo del grado de indisposición del desarrollador, podrá no realizar ninguna actividad, o quizás puede realizar las que menos esfuerzo le requieran, intentando así que la planificación se vea lo menos afectada posible. En caso de que no pueda realizar ninguna tarea relativa al proyecto, habría que reajustar la planificación. Tabla 4.5. RIE-004. Indisponibilidad del desarrollador
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 57 RIE-005 Avería en el ordenador Categoría Proyecto 3 Probabilidad Muy baja Impacto Alto Descripción El ordenador que se está utilizando para el desarrollo del software puede sufrir algún tipo de avería. Fases afectadas -Elaboración -Construcción Gestión de riesgo Estrategia Protegernos del riesgo Plan de mitigación Tener otro ordenador de características similares disponible para poder continuar realizando el trabajo sin que, o afectando lo mínimo posible, la planificación inicial. Plan de contingencia Empezar a usar el ordenador mencionado anteriormente y continuar realizando el trabajo. Tabla 4.6. RIE-005. Avería en el ordenador
Desarrollo del proyecto 64 Fase Iteración Semanas Fecha Inicio Fecha Fin Inicio 1 1 22/02/19 26/02/19 Elaboración 2 5 27/02/19 02/04/19 Construcción 3 11 03/04/19 19/06/19 Transición 1 1 jue 20/06/19 26/06/19 Tabla 4.12. Vista general de las fases del proyecto Vamos a explicar las fases e iteraciones principales en las que se va a dividir el proyecto: • Fase 1: Primera iteración de Inicio. En esta fase se desarrollará el documento de diseño del videojuego (GDD). Nombre de tarea Duración Comienzo Fin Iniciación 3 días vie 22/02/19 mar 26/02/19 Tabla 4.13. Contenido primera iteración de Inicio • Fase 2: Primera iteración de Elaboración. En esta fase se comenzará con la toma de requisitos y análisis de estos. Así como de la identificación de los casos de uso. Nombre de tarea Duración Comienzo Fin Toma de requisitos 2 días mié 27/02/19 jue 28/02/19 Análisis de los requisitos 2 días vie 01/03/19 lun 04/03/19 Realización de los casos de uso 1 día mar 05/03/19 mar 05/03/19 Descripción detallada de los casos de uso 3 días mié 06/03/19 vie 08/03/19 Tabla 4.14. Contenido primera iteración de Elaboración
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 65 • Fase 3: Segunda iteración de Elaboración. En esta fase se realizará el diseño del sistema. Nombre de tarea Duración Comienzo Fin Realización del modelo de dominio 3 días lun 11/03/19 mié 13/03/19 Realización del modelo entidad-relación 3 días jue 14/03/19 lun 18/03/19 Modelo de dominio (Diseño) 4 días mar 19/03/19 vie 22/03/19 Diagramas de secuencia 7 días lun 25/03/19 mar 02/04/19 Tabla 4.15. Contenido segunda iteración de Elaboración • Fase 4: Primera iteración Construcción. Se comenzará con la formación del equipo en la herramienta Unity. En esta fase se marca como hito, y, por lo tanto, se implementará el movimiento del personaje con el joystick, así como la gestión de objetos y los modificadores de las estadísticas del usuario. Nombre de tarea Duración Comienzo Fin Formación en Unity 5 días mié 03/04/19 mar 09/04/19 Construcción (Etapa 1) 17 días mié 10/04/19 jue 02/05/19 Tabla 4.16. Contenido primera iteración de Construcción • Fase 5: Segunda iteración Construcción. En esta fase se marca como hito, y, por lo tanto, se implementará el HUD y el lanzamiento de las habilidades, así como la personalización de los sets de habilidades. Nombre de tarea Duración Comienzo Fin Construcción (Etapa 2) 17 días vie 03/05/19 lun 27/05/19 Tabla 4.17. Contenido segunda iteración de Construcción • Fase 6: Tercera iteración de Construcción. En esta fase se marca como hito, y, por lo tanto, se adaptará todo lo anterior a la red, así como la realización de la gestión de final de partida y emparejamiento para conformarlas.
Desarrollo del proyecto 66 Nombre de tarea Duración Comienzo Fin Construcción (Etapa 3) 17 días mar 28/05/19 mié 19/06/19 Tabla 4.18. Contenido tercera iteración de Construcción • Fase 7: Primera iteración de Transición. Se realizarán las pruebas unitarias para comprobar que todo el sistema funciona correctamente, además de los manuales. Nombre de tarea Duración Comienzo Fin Transición 5 días jue 20/06/19 mié 26/06/19 Tabla 4.19. Contenido primera iteración de Transición El diagrama de Gantt global del proyecto es el siguiente. Figura 4.2. Diagrama de Gantt del proyecto Como podemos ver en el diagrama de Gantt, comenzaríamos con la fase de iniciación que duraría unos 3 días. Después se llevará a cabo la primera fase de elaboración, que iría desde el Análisis de los requisitos hasta la Descripción detallada de los casos de uso. Le sigue la segunda fase de elaboración, que comprendería desde la Realización del modelo de dominio inicial hasta los Diagramas de secuencia. Una vez acabada la fase de Elaboración, comenzaremos la fase de Construcción, en la cual habrá tres fases, los hitos que denotan el final de cada fase los mencionaremos más adelante. En último lugar, se finalizará el proyecto con la fase de Transición.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 67 Se calcula que el tiempo total del desarrollo del proyecto será de 17 semanas aproximadamente. Las horas de trabajo se contabilizarán de manera semanal, a un promedio de 18 horas de trabajo semanales. Resultaría un total de 306 horas. 4.3.3. Costes de producción previstos Una vez realizada la planificación y su división en fases, así como la enumeración de los roles, vamos a proceder a estimar los costes totales del proyecto. Independientemente de los roles que se vaya a tomar en el desarrollo del proyecto, en cuanto al coste de los recursos humanos vamos a calcular como si de un trabajador autónomo con titulación de ingeniero informático se tratara. Se estiman los honorarios por hora en 12€. Por lo tanto, en cuanto al coste de los recursos humanos tendremos un total de 3.672€. A parte de los costes humanos, también hay que tener en cuenta el coste material. En nuestro caso, todo el software que hemos utilizado ha sido bien de uso libre, o bien bajo licencias provistas por la universidad, como es el caso de MS Project y Astah, por lo que no ha supuesto ningún coste añadido. En la siguiente tabla declararemos los gastos materiales asignados al proyecto. Como es obvio, no se espera que este proyecto asuma los costes íntegros de todos los recursos, por eso se ha calculado la parte proporcional a las 18 horas semanales que dedicaremos al proyecto. Recurso Precio mensual Coste total Amortización del hardware 30€ 120€ Conexión a internet 10€ 40€ Alquiler 80€ 320€ Suministro eléctrico 12€ 48€ Material de oficina 4€ 16€ Tabla 4.20. Recursos materiales El coste total de los recursos materiales y de alojamiento del proyecto asciende a 544€. Si calculamos el coste total previsto del proyecto, obtenemos un coste estimado de 4.216€.
Desarrollo del proyecto 68 4.3.4. Seguimiento del proyecto A continuación, describimos cómo ha resultado la planificación final del proyecto, si nos hemos ajustado a los plazos, o, si ha aparecido algún riesgo y cómo lo hemos afrontado. El proyecto comenzó según lo esperado, las primeras fases se realizaron de forma correcta, al menos sus primeras iteraciones. Sin embargo, en las primeras fases de construcción se materializó el riesgo (RIE-001), relacionado con los problemas de implementación con Unity. Era un riesgo que habíamos calculado con probabilidad media, ya que contábamos con que la curva de aprendizaje no sería complicada, y así lo fue. El problema fueron unos errores que el equipo no era capaz de solventar y mantuvo estancada la implementación algo más de una semana. Durante este tiempo, con el objetivo de mantener la planificación por fechas intacta, se incrementó el número de horas diarias hasta que el problema estuvo resuelto y se pudo volver a la normalidad. Una vez superada la curva de aprendizaje y asimilados los errores que ralentizaron el proyecto, fue todo bastante fluido. Se detectaron algunos errores, pero que no daban problemas más allá de un par de días, y que entraban dentro de lo planeado. Durante la fase de construcción, se seguían refinando las fases de análisis y diseño, por suerte, ninguno de los cambios que se hicieron repercutió de manera negativa en el desarrollo del proyecto, ya que eran cuestiones más finas, que no se habían empezado a implementar aún, por lo que el riesgo de que afectaran negativamente (RIE-002) no llegó a cumplirse. En cuanto al resto de los riesgos, ninguno llegó a materializarse. Afortunadamente no hubo pérdidas de información, aunque el plan de mitigación se continuó realizando hasta el final del proyecto. En cambio, en la tercera fase de construcción, ocurrió el riesgo relativo a los problemas de la implementación en red (RIE-008). La planificación inicial contaba con la alta probabilidad de ocurrencia de este riesgo. Gracias a que se contaba con ello, el equipo necesitó incrementar el número de horas diarias en menor medida que con el RIE-001 ya que, al tener éste una probabilidad más alta, se calculó un tiempo de resolución más holgado. La ampliación de horas en estas fases hizo aumentar la media de horas semanales dedicadas al proyecto hasta un total de 20. Por tanto, habría que recalcular los costes tanto humanos como materiales. El nuevo cálculo de horas totales dedicadas al proyecto es de 340. Por tanto, el coste de recursos humanos asciende ahora a 4.080€. También tenemos que aumentar la parte proporcional de los recursos materiales, lo que nos deja 604€. Obtenemos entonces un coste final total de 4.684€.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 69 Debido a la inexperiencia en la planificación de proyectos y que se trata de un campo del que no se tenían apenas conocimientos previos, la planificación inicial no se ha cumplido correctamente y han surgido unos sobrecostes de 468€.
Desarrollo del proyecto 70
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 71 5. Análisis 5.1. Propósito general La aplicación deberá permitir al usuario jugar una partida de nuestro videojuego al pulsar el botón “Jugar”. Una vez pulsado, el sistema de emparejamiento buscará uno o varios jugadores disponibles y comenzará una partida entre todos ellos. Las mecánicas del juego serán descritas más en profundidad en otros apartados. Además de jugar, el sistema deberá permitir al usuario personalizar las habilidades del personaje con el que desea jugar, así como algunas opciones de sonido y video. 5.2. Alcance del sistema El sistema realizará tanto el entorno y componentes del juego, como la navegación y lógica interna del mismo con ayuda del motor gráfico Unity. La parte relativa a la conectividad multijugador se realizará con ayuda de la API que Unity tiene destinada para ello, UNET. 5.3. Requisitos del sistema Un requisito [40] es una “condición o capacidad que necesita el usuario para resolver un problema o conseguir un objetivo determinado”. También se consideran requisitos las condiciones que debe poseer o cumplir un sistema para satisfacer un contrato, norma o especificación. Es decir, puede verse tanto como una declaración abstracta, comúnmente de alto nivel, de un servicio que el
Análisis 72 sistema debe proporcionar, o como una definición matemática detallada de una función o restricción del sistema. Vamos a serparar, en dos grupos, los requisitos funcionales y los no funcionales. 5.3.1. Requisitos funcionales Los requisitos funcionales definen los servicios que el sistema debe proporcionar, cómo debe reaccionar a una entrada concreta y cómo se debe comportar según qué situaciones. RF-001 Crear partida Descripción El sistema deberá permitir al usuario crear una partida. Tabla 5.1. RF-001. Crear partida RF-002 Descubrir partida Descripción El sistema deberá permitir al usuario que descubra partidas que otros usuarios hayan creado. Tabla 5.2. RF-002. Descubrir partida RF-003 Unirse a una partida creada Descripción El sistema deberá permitir al usuario unirse a una partida creada por otro usuario. Tabla 5.3. RF-003. Unirse a una partida creada RF-004 Iniciar la partida Descripción El sistema deberá permitir al usuario pulsar el botón de “preparado” y, si el resto de los jugadores lo han pulsado también, dar comienzo a la partida. Tabla 5.4. RF-004. Iniciar partida RF-005 Finalizar partida Descripción El sistema deberá dar por acabada la partida cuando solo quede un jugador con vida superior a 0 o bien cuando acabe el tiempo límite. Tabla 5.5. RF-005. Finalizar partida
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 73 RF-006 Movimiento del personaje Descripción El sistema deberá permitir al personaje moverse (en todas direcciones) con ayuda de un joystick situado a la parte izquierda de la pantalla. Tabla 5.6. RF-006. Movimiento del personaje RF-007 Lanzamiento de habilidades Descripción El sistema deberá permitir al personaje lanzar las habilidades que tenga (en todas direcciones) con ayuda de un joystick situado a la parte derecha de la pantalla. Tabla 5.7. RF-007. Lanzamiento de habilidades RF-008 Impactar habilidades Descripción El sistema deberá permitir que el personaje sea alcanzado por habilidades lanzadas por otros usuarios y que le realicen daño basado en el ataque del lanzador y la defensa del receptor. Tabla 5.8. RF-008. Impactar habilidades RF-009 Alteración de los atributos de los personajes Descripción El sistema deberá permitir que, bajo las circunstancias descritas en el juego, los atributos (vida, velocidad, ataque, defensa, etc) de los personajes se vean afectados tanto por habilidades como por objetos y cambien. Tabla 5.9. RF-009. Alteración de los atributos de los personajes RF-010 Recogida de objetos en el suelo Descripción El sistema deberá permitir que los personajes recojan los objetos que salgan en el suelo del campo de batalla al pasar por encima de ellos y que, al hacer esto, realicen su funcionalidad. Tabla 5.10. RF-010. Recogida de objetos en el suelo
Análisis 80 5.3.3.2.3. Impactar habilidades UC-003 Impactar habilidades Actor Jugador Precondición Un proyectil de habilidad ha sido lanzado y está viajando por el campo de batalla en una dirección. Postcondición Si se encuentra con algún jugador, que no haya sido el mismo lanzador, le afecta la habilidad impactada y realiza daño calculado entre el ataque del lanzador y la defensa del receptor. Si no encuentra ninguno, llegado el final de su rango, desaparece Secuencia base 1. El sistema continúa moviendo por el campo de batalla el proyectil hasta que golpea a un jugador. El caso de uso continúa en [Alterar atributos de los personajes]. Secuencia alternativa 1b. El sistema continúa moviendo por el campo de batalla el proyectil hasta que agota su distancia recorrida, conocida como "rango" y al ocurrir esto, el proyectil desaparece. Comentarios adicionales Tabla 5.25. UC-003. Impactar habilidades
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 81 5.3.3.2.4. Recoger objetos UC-004 Recoger objetos Actor Jugador Precondición El personaje tiene que estar vivo en el campo de batalla y moviéndose. Postcondición El personaje ha pasado por encima de un objeto y lo ha recogido. Secuencia base 1. El usuario mueve al personaje hasta un objeto, hasta que pasa por encima de él. 2. El sistema procesa que ese personaje ha recogido ese objeto, lo hace desaparecer del campo y continúa por el caso de uso Alterar atributos de los personajes. Secuencia alternativa Comentarios adicionales Tabla 5.26. UC-004. Recoger objetos
Análisis 82 5.3.3.2.5. Alterar atributos de los personajes UC-005 Alterar atributos de los personajes Actor Jugador Precondición El personaje ha sido afectado por alguna de las situaciones en las que tiene lugar la alteración de sus atributos, como es el impacto por parte de una SkillshotProjectile o al recoger un objeto. Postcondición Los atributos pertinentes son alterados Secuencia base 1. El sistema reconoce qué modificador (PlayerModifier) es el que afecta al personaje y le altera los atributos pertinentes. También calcula junto con la duración del PlayerModifier, el momento en el tiempo en el que esa modificación se tiene que revertir (tiempoFinalModifier), lo que daría paso al caso de uso Revertir atributos de los personajes. Secuencia alternativa Comentarios adicionales Esta situación viene derivada de una acción de un jugador, por tanto, el actor es el jugador, aunque no participe activamente en este caso de uso. Tabla 5.27. UC-005. Alterar atributos de los personajes
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 83 5.3.3.2.6. Revertir atributos de los personajes UC-006 Revertir atributos de los personajes Actor Tiempo Precondición El personaje ha sido afectado anteriormente por una alteración de atributos de personajes. Postcondición La alteración de atributos original se revierte. Secuencia base 1. Cuando llega el instante calculado anteriormente con esa alteración de atributos (tiempoFinalModifier), el sistema revierte los atributos específicos que se cambiaron en un inicio. Secuencia alternativa Comentarios adicionales Tabla 5.28. UC-006. Revertir atributos de los personajes
Análisis 84 5.3.3.2.7. Identificarse UC-007 Identificarse Actor Jugador Precondición Si se quiere acceder a los datos de un perfil ya creado, el usuario tiene que estar dado de alta en el sistema. Postcondición El usuario está identificado en el sistema. Secuencia base 1. El usuario introduce su nombre de usuario. 2. El sistema comprueba si el nombre de usuario existe. Si existe recupera de la base de datos los datos de las configuraciones de los kits del usuario. Secuencia alternativa 2b. El sistema comprueba si el nombre de usuario existe. Si no existe crea una configuración básica por defecto para que el nuevo usuario pueda configurar, ya con este nombre de usuario, sus kits de habilidades. Comentarios adicionales Este caso de uso sería como “registrarse” e “identificarse” en uno solo. Como no hay un registro como tal, ambas secuencias posibles están en este caso de uso. Tabla 5.29. UC-007. Identificarse
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 85 5.3.3.2.8. Seleccionar kit de habilidades UC-008 Seleccionar kit de habilidades Actor Jugador Precondición El usuario tiene que estar previamente identificado con su nombre de usuario. Postcondición Se selecciona el kit de habilidades deseado y se va a la escena de personalización. Secuencia base 1. El usuario selecciona un kit de habilidades haciendo clic en él para personalizarlo. 2. El sistema redirige a la escena de personalización del kit seleccionado. Secuencia alternativa 1b. El usuario hace clic sobre la estrella a la derecha de cada kit de habilidades para marcar el deseado como favorito. 2b. El sistema marca como nuevo favorito el kit de habilidades elegido Comentarios adicionales Tabla 5.30. UC-008. Seleccionar kit de habilidades
Análisis 86 5.3.3.2.9. Personalizar kit de habilidades UC-009 Personalizar kit de habilidades Actor Jugador Precondición El usuario ha seleccionado previamente qué kit de habilidades quiere personalizar. Postcondición El kit de habilidades queda guardado de acuerdo con las preferencias del usuario. Secuencia base 1. El usuario pulsa sobre el nombre para editarlo. 2. El sistema permite al usuario introducir el nombre y lo guarda en el espacio destinado para el nombre. 3. El usuario selecciona una Skillshot de las disponibles 4. El sistema muestra la información de la Skillshot en pantalla 5. El usuario puede elegir escogerla como una de las deseadas pulsando seguidamente en una de las tres ranuras para colocarlas. 6. El sistema asigna la Skillshot a la ranura. 7. El usuario pulsa la pestaña "Pasivas" 8. El sistema oculta las Skillshots disponibles y en su lugar aparecen las pasivas disponibles. 9. El usuario selecciona una pasiva de las disponibles 10. El sistema muestra la información de la pasiva en pantalla 11. El usuario puede elegir escogerla como una de las deseadas pulsando seguidamente en una de las tres ranuras para colocarlas. 12. El sistema asigna la pasiva a la ranura. 13. El usuario pulsa el botón de Guardar. 14. El sistema guarda todos los cambios de ese kit de habilidades en el sistema de forma permanente. Secuencia alternativa 13b. En caso de que se realice cualquier otro cambio y se salga sin pulsar el botón de guardar, esos cambios no quedarán guardados. Comentarios adicionales El orden de edición de los distintos elementos personalizables dentro de esta escena no tiene que ser necesariamente como indica la secuencia base, al menos del paso 3 al paso 11, sino que pueden alternarse y repetirse tantas veces como considere el usuario, siempre y cuando el paso de guardar sea el último. Tabla 5.31. UC-009. Personalizar kit de habilidades
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 87 5.3.3.2.10. Crear partida UC-010 Crear partida Actor Jugador Precondición El usuario tiene que estar previamente identificado con su nombre de usuario. Postcondición El usuario ha creado una partida en el servidor. Secuencia base 1. El jugador introduce el nombre de la partida, por el cual desea que sea buscada y pulsa "Crear partida" 2.El sistema envía la petición al servidor, si todo va bien, la sala de la partida se crea y el usuario es introducido en ella. Secuencia alternativa Comentarios adicionales Tabla 5.32. UC-010. Crear partida 5.3.3.2.11. Descubrir partidas creadas UC-011 Descubrir partidas creadas Actor Jugador Precondición El usuario tiene que estar identificado en el sistema. Postcondición El usuario descubre todas las partidas que está almacenando el servidor en ese momento. Secuencia base 1. El usuario pulsa el botón "Descubrir partidas". 2. El sistema envía la petición al servidor y este responde con las partidas que tiene almacenadas y disponibles para unirse en ese momento. El sistema le muestra al usuario un listado de ellas. Secuencia alternativa Comentarios adicionales Tabla 5.33. UC-011. Descubrir partidas creadas
Análisis 88 5.3.3.2.12. Unirse a partida creada UC-012 Unirse a partida creada Actor Jugador Precondición El usuario debe haber realizado el caso de uso [Descubrir partidas creadas] con anterioridad Postcondición El usuario se une a la partida deseada. Secuencia base 1.El usuario identifica la partida a la que quiere unirse y pulsa el botón de "Unirse". 2.El sistema manda la petición al servidor y se incluye al usuario en la sala de la partida. Secuencia alternativa Comentarios adicionales Tabla 5.34. UC-012. Unirse a partida creada
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 89 5.3.3.2.13. Pulsar botón de “preparado” UC-013 Pulsar botón de “preparado” Actor Jugador Precondición El jugador tiene que estar dentro de una sala de partida. Postcondición Si los demás usuarios también han pulsado el botón, se dará paso al caso de uso [Iniciar Partida]. Secuencia base 1. El usuario personaliza su nombre de partida y el color con el que quiere jugar y pulsa el botón de "Preparado" cuando lo está. 2. El sistema manda esa actualización al servidor para que se actualice en la sala de espera del resto de jugadores. Si éste era el último en estar preparado, se da paso al caso de uso [Iniciar Partida]. Secuencia alternativa 2b. El sistema manda esa actualización al servidor para que se actualice en la sala de espera del resto de jugadores. El jugador y el resto de ellos que ya hayan pulsado el botón deben esperar a que el último pulse el botón y así poder dar paso al caso de uso [Iniciar Partida]. Comentarios adicionales Tabla 5.35. UC-013. Pulsar el botón de “preparado”
Diseño 96 Estas sirven para rotar y trasladar el objeto los grados y dirección, respectivamente, de los objetos. 6.1.1.5. Renderer Un Renderer es el que hace que los objetos aparezcan y sean visibles en la escena. Entre los tipos de Renderer, el que más vamos a utilizar es el SpriteRenderer. 6.1.1.6. Collider Los colliders permiten definir las superficies de colisión de los objetos de las escenas. Se pueden crear collider con muchas formas, por ejemplo, círculos, triángulos, cuadrado, etc. El que más usaremos será Box Collider 2D. 6.1.1.7. Behaviour Los behaviours son componentes que se pueden activar y desactivar. El que vamos a utilizar más, y por tanto desarrollamos a continuación es MonoBehaviour, que, debido a su importancia, tiene un apartado al nivel de Component. 6.1.1.8. MonoBehaviour MonoBehaviour es la clase base de la cual todos los scripts de Unity heredan. Cuando usemos C# para los scripts, hay que heredar explícitamente de MonoBehaviour. Al crear un script y heredar de MonoBehaviour lo que hacemos es darle un comportamiento en concreto a un GameObject, al cual le asignaremos este script (MonoBehaviour) como un componente más. Dentro de este script podemos definir lo que nuestro GameObject hará dentro de la escena, controlando el resto de sus componentes con nuestro código. Al crear un script desde el editor, automáticamente se nos genera con varias funciones, pertenecientes a MonoBehaviour. Éstas son: 6.1.1.8.1. Start Start es una función que se llama en el primer frame (fotograma) en que el script es activado, justo antes de cualquiera de las llamadas a Update. Se suele usar, como Awake, para la inicialización de variables.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 97 6.1.1.8.2. Update Update es una función que es llamada cada frame, si el MonoBehaviour está activo. Update es la función más utilizada para implementar cualquier tipo de comportamiento. Por ejemplo, si queremos hacer andar a un personaje, debemos hacer una pequeña traslación en cada frame, para dar al jugador la sensación de que, en cada fotograma, el personaje avanza poco a poco. Existen otras funciones muy útiles, que, aunque no sean las dos principales, pueden proporcionar otras posibilidades que las dos funciones mencionadas anteriormente no pueden dar. Son las siguientes. 6.1.1.8.3. Awake Awake se llama cuando la instancia del script está siendo cargada. Solamente se llama una vez en el ciclo de vida de la instancia de ese script, justo al principio. Es una función que se ejecuta justo antes que Start y te asegura que se va a ejecutar siempre antes que el Start de cualquier otro GameObject de la escena. Esto puede ser muy útil para localizar objetos en la escena sin miedo a que algún Start de otro objeto se haya ejecutado y que esto pueda provocar un error. Se suele usar, como Start, para la inicialización de variables. 6.1.1.8.4. FixedUpdate Con un comportamiento similar a Update pero con la singularidad de que tiene la frecuencia del sistema de físicas. Es llamada a un ritmo constante, cada 0.02 segundos (50 llamadas por segundo) que es el tiempo por defecto entre llamadas. Para acceder a este valor se puede con Time.fixedDeltaTime. Una especialización de MonoBehaviour que no aparece en el diagrama anterior pero sí vamos a utilizar es NetworkBehaviour, orientado al uso de redes en los juegos. Contiene multitud de variables y métodos que son muy útiles para el manejo y gestión de la partida en red. Hablaremos un poco más en detalle de lo que nos ofrece en el apartado de implementación.
Diseño 98 6.2. Modelo de dominio En este apartado veremos, en primer lugar, un modelo de dominio que solamente representa las clases que realmente son “importantes” y representan al dominio de la cuestión. Todas tienen una función bien definida y son vitales para el desarrollo del videojuego. Más adelante mostraremos un diagrama ampliado con la totalidad de las clases que participan en el correcto funcionamiento del proyecto. Figura 6.2. Modelo de dominio del proyecto Con el objetivo de evitar la redundancia y repetición a la hora de hablar de cada una de las clases, en el diagrama se colorearán las clases para diferenciarlas. La diferenciación radica en la clase de la que hereda cada una. Es preferible hablar de las particularidades de cada una en su apartado y hablar de las herencias y el porqué de ellas, como grupo, aquí. En primer lugar, hablaremos de las coloreadas en amarillo, que, son clases, que no heredan de ninguna clase más que de la raíz. Esto se debe a que no necesitamos que estas clases tengan un comportamiento de un Behaviour o de un Component, quizás ni siquiera queremos que ese elemento aparezca en la escena, simplemente necesitamos una clase sencilla para albergar atributos y funciones muy específicas que nada tienen que ver con los elementos mencionados anteriormente. Es el caso, por ejemplo, de las Skillshots y los PlayerModifier, entre otros. ¿Por qué necesitamos que estas clases sean simples? Porque las vamos a usar como una clase normal. Solo queremos consultar sus atributos y ejecutar sus funciones, pero no necesitamos que, por ejemplo, ocurra algo cada vez que se recarga la pantalla (funciones Update y
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 99 FixedUpdate). Las tendremos como “almacenadores de información” muy valiosa para el juego, pero no como elementos de la escena como tal. El siguiente grupo son los coloreados de verde. Estas clases son las que heredan de MonoBehaviour. Son clases que, a diferencia de las anteriores sí vamos a querer que tengan un espacio en nuestras escenas, porque va a ser necesario que en cada refresco de pantalla realicen alguna acción, o que simplemente vayan a aparecer en la escena. El ejemplo más claro es el HUD. Por último, el grupo morado. Estas clases son las que heredan de NetworkBehaviour. Las queremos básicamente para lo mismo que las anteriores, las del grupo verde, con la particularidad de que estas clases van a ser usadas expresamente en red. Debido a esto, van a tener que heredar de NetworkBehaviour porque les provee de ciertos métodos y variables que van a ser muy necesarios para desarrollar sus actividades en red. Los VirtualJoystick también van a heredar de esta clase, aunque a priori pueda parecer que no es necesario ya que “forman parte” del HUD. Esto es debido a que no solamente es necesario para las clases que vayan a usar explícitamente los métodos que brinda NetworkBehaviour, sino que, en ocasiones, como el caso que mencionamos, es necesario que lo hereden porque van a ser importantes en la red y necesitan tener un componente llamado NetworkIdentity (identificación en red). Sin que hereden de NetworkBehaviour no se puede añadir este componente. 6.2.1. Clases del modelo de dominio 6.2.1.1. User La clase en la cual estará la información del usuario, con la que el usuario podrá identificarse en el servidor y en el que se guardarán sus progresos. 6.2.1.2. UserAbilitySet Esta clase sirve para albergar un conjunto, en principio 3, de varios AbilitySet pertenecientes al usuario (User) que esté jugando. 6.2.1.3. AbilitySet Esta clase, como su nombre indica, va a ser el “Set de habilidades”. Consistirá en un conjunto de 3 Skillshots y 3 PlayerModifier que el usuario podrá personalizar a su gusto con los disponibles para escoger. También podrá marcar
Diseño 100 uno de los 3 de los que dispone como favorito (es con el que jugará cuando decida iniciar la partida). 6.2.1.4. PlayerModifier Esta clase, como su nombre indica contendrá los “Modificadores del jugador”. Sus atributos serán la duración que tenga este modificador, nombre, descripción y, además, un conjunto de SingleModifier. 6.2.1.5. SingleModifier Esta clase contendrá simplemente la estadística a modificar del jugador y la intensidad con la que esta modificación se produce (una modificación muy fuerte o una más leve). Cada PlayerModifier tiene un conjunto de SingleModifiers. Cuando a un Player le afecta el PlayerModifier, se van afectando todos los SingleModifier que le contienen. 6.2.1.6. Item Clase que describe a un “objeto” que aparecerá de manera aleatoria en el suelo. Contiene información sobre su codigoItem, útil para saber qué imagen le corresponde. Además de, lo más importante, un PlayerModifier asociado que describirá los efectos que tiene sobre los jugadores al recoger este objeto del suelo. 6.2.1.7. ItemInstance Es la representación “física” del objeto en la escena. Contendrá la información sobre el ítem al que representa. 6.2.1.8. Skillshot Clase que describe los “ataques” o “disparos” dentro del juego. Tendrá diversos atributos como nombre, descripción, damage (daño), rango (rango máximo al que llegará el disparo antes de desaparecer sin golpear a nadie), velocidad, cooldown (enfriamiento para reutilizarse), etc. Todos estos atributos conforman una Skillshot, la diferenciación de los distintos atributos hace que cada Skillshot sea distinta. Así mismo se dispondrá de un “códigoSkillshot” el cual nos será útil
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 101 para identificar la imagen que se usará para diferenciarse de otros Skillshot, entre otros usos. 6.2.1.9. MovingObject Clase abstracta que describe el funcionamiento y contiene algo de implementación común de los objetos que serán “movibles” dentro del juego, que son los que describiremos a continuación. 6.2.1.10. SkillshotProjectile Clase que hereda de MovingObject, por tanto, objeto movible del juego. Lo que representa esta clase son los proyectiles de las Skillshot. Las Skillshots solamente describían sus atributos, pero los SkillshotProjectile son los proyectiles que el jugador va a poder ver cómo impactan sobre él o cómo impacta con ellos a sus rivales. 6.2.1.11. Player Clase de manejo del jugador o “personaje”. Obviamente será un heredado de MovingObject ya que el jugador va a poder mover al personaje por el campo para intentar esquivar los SkillshotProjectile y para recoger los objetos. Contendrá mucho código referente al movimiento, a la trata (afectar y revertir) PlayerModifier, afectar SkillshotProjectile recibidas, etc. Entre sus atributos tendremos la vida, la vida máxima, el ataque, la defensa, la velocidad (heredada), etc. 6.2.1.12. HUD Esta clase manejará el HUD, la interfaz de la que dispondrá el jugador para saber la información referente a su personaje en todo momento. Para ayudar a esto, el HUD se compondrá de varios elementos, algunos de ellos los describiremos a continuación, otros, al carecer de importancia o no ser una clase nueva implementada, los obviaremos, ya que solo son para mejorar y hacer más intuitiva la experiencia de juego del usuario.
Diseño 102 6.2.1.13. VirtualJoystick Clase que manejará el joystick situado a la parte izquierda de la pantalla, el cual manipulará el movimiento del personaje. Forma parte del HUD. 6.2.1.14. VirtualJoystickSkillshot Clase que hereda de VirtualJoystick, ya que comparten mucha implementación y su forma básica de funcionar es prácticamente la misma, con la diferencia de que VirtualJoystickSkillshot contendrá la imagen de una Skillshot y al soltar el cursor con una dirección, el personaje lanzará la Skillshot asociada a este objeto. Además de esto, al contener cada uno una Skillshot y usarla cuando se use el joystick, este entrará en “enfriamiento” y no se podrá lanzar más esa habilidad hasta que no se reestablezca. Forma parte del HUD. 6.2.1.15. TextStats Sencilla clase que solo se utilizará para mantener actualizadas las estadísticas y atributos del personaje para mostrar la información en todo momento a través del HUD. 6.3. Arquitectura lógica La elección de la arquitectura [42] de un producto software tan complejo y extenso como es un videojuego puede resultar difícil. Dependiendo de en qué nos centremos, podemos pensar que el patrón arquitectónico puede ser Modelo- Vista-Controlador. Y así podría ser si solamente nos fijáramos en la parte de personalización y menús, pero la principal funcionalidad de este proyecto reside en la partida y la jugabilidad, que mucho distan de un Modelo-Vista-Controlador. Hay un patrón arquitectónico que se ajusta más a este sistema de eventos por los cuales el usuario va a realizar cambios en el sistema. Este patrón es la Arquitectura Dirigida por Eventos (EDA). Esta arquitectura se centra en la creación, detección, consumo y reacción de eventos (por ejemplo, en Unity tenemos la clase EventSystem [43]). Nos referimos a evento como cualquier acción, venga del usuario o no que provoque un cambio significativo en un estado de algún elemento del sistema. La arquitectura EDA consta de cuatro capas lógicas, cada una con su función definida que explicamos a continuación.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 103 1. Generador de Eventos. En esta capa se detectan las apariciones de un hecho y genera el evento relacionado con ese hecho en consecuencia. Después transmiten ese evento al Canal de Eventos. 2. Canal de Eventos. Esta capa consiste en un mecanismo mediante el cual la información que le ha llegado desde un generador de eventos se transfiere al Motor de Procesamiento de Eventos. 3. Motor de Procesamiento de Eventos. El motor de esta capa es el encargado de identificar un evento y asignarle la respuesta que corresponda. 4. Respuesta al Evento. Es la parte final de la captura del evento. Esta capa muestra los resultados de la aparición del evento. Figura 6.3. Arquitectura Dirigida por Eventos Esta última capa representa la respuesta final que queremos que tenga este evento concreto, en nuestro caso los menús con botones tendrán su acción indicada en forma de función de una clase (como explicamos más adelante) y los joysticks realizan sus acciones mediante los métodos que se explican en el apartado del capítulo de Implementación relativo al movimiento.
Diseño 104 6.4. Patrones de diseño Christopher Alexander [44] reconocido arquitecto, define en los patrones de la siguiente manera. “Cada patrón describe un problema que ocurre una y otra vez en nuestro entorno para describir después el núcleo de la solución a ese problema, de tal manera que esa solución pueda ser usada más de un millón de veces sin hacerlo siquiera dos veces de la misma forma”. ALEXANDER, C., ET AL.A PATTERN LANGUAGE: TOWNS, BUILDINGS, CONSTRUCTION, OXFORD UNIVERSITY PRESS, (1977). Llevado al campo de la informática y, en concreto, del desarrollo, los patrones de diseño [45] son realmente útiles para afrontar problemas que surgen a la hora de diseñar un sistema. Nos ayudan a ver cómo, gente que ha tenido anteriormente los mismos problemas que nosotros, han consensuado que una forma más o menos concreta de solucionarlo es una de las mejores maneras para afrontarlos. 6.4.1. Patrones de diseño propuestos por Unity Al trabajar con un entorno de desarrollo como Unity, con una API propia para ayudarnos a trabajar con los elementos del juego, es normal encontrar que propicie el uso de determinados patrones de diseño, a parte de los que el diseñador encuentre necesario utilizar para el juego en concreto. 6.4.1.1. Flyweight El patrón Flyweight, también conocido como objeto ligero, sirve para reducir la redundancia de información idéntica en objetos que van a aparecer en la escena en gran número. De esta manera, si tenemos, por ejemplo, cientos de baldosas iguales en el suelo, la información idéntica que tengan entre sí, se aprovecha, no ocupando la misma memoria todos y cada uno como si fueran objetos totalmente distintos. Toda la información como color, tamaño y lo que compartan, es la misma, y simplemente ocuparán más memoria los atributos que sí distingan cada una entre sí, como por ejemplo la posición exacta de cada una.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 105 6.4.1.2. State El patrón State, o Estado, se utiliza cuando el distinto comportamiento de un objeto depende del estado de este. El patrón es usado para las máquinas de estados que sirven para gestionar las animaciones, que veremos más adelante. Simplemente dependiendo de la dirección en la que se esté moviendo el personaje, le diremos que está en un estado o en otro (por ejemplo, arriba a la izquierda o a la derecha). Entonces, cada objeto animación, dependiendo del estado en el que se encuentre el personaje, actuará a su manera. 6.4.2. Patrones de diseño elegidos para el proyecto 6.4.2.1. Singleton El patrón Singleton, o instancia única, es un patrón que obliga a que solo pueda haber un objeto de esa clase instanciado a la vez. Esto tiene muchas ventajas, la principal y más importante es que permite el acceso global a dicho objeto en todo momento y desde cualquier sitio. Figura 6.4. Estructura básica de clase aplicando Singleton Como podemos ver, para obtener la instancia, se llama a un método de clase (la forma de acceder a ello de forma global) y ese método nos da la instancia que está creada en ese momento y que mantiene todos sus atributos. Hemos pensado que para nuestra aplicación sería muy útil tener una clase que albergara toda la información que tiene que estar activa y accesible mientras el juego esté activo. Por consiguiente, la utilización del Singleton va a centrarse en una clase llamada GameManager. Esta clase se creará desde el inicio del juego y permanecerá con una instancia desde entonces hasta que lo cerremos, albergando en su interior todos los recursos que puedan ser necesarios para acceder de manera global a ellos. Podremos acceder desde las pantallas de personalización, guardando configuración en ella, así como desde la pantalla de juego.
Diseño 112 6.6.2. Diagrama de secuencia de SkillshotProjectile Figura 6.11. Diagrama de secuencia de SkillshotProjectile
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 113 7. Implementación El desarrollo de videojuegos requiere de más tareas que la simple programación de código. Obviamente, es una parte muy importante y vital para que el videojuego funcione tal y como deseamos, pero para que el videojuego sea, entre otras cosas, atractivo a la vista, no podemos olvidarnos de las demás actividades necesarias. Entre ellas el manejo de animaciones, la creación manual de elementos de la escena desde el editor de Unity, la creación de los elementos visuales con herramientas como Piskel o la gestión de la base de datos. Esta última se hará a través de una clase auxiliar llamada SQLiteManager, que explicaremos más adelante. 7.1. Jugabilidad El videojuego es un sistema interactivo un tanto especial, ya que está orientado a divertir y entretener al usuario, no a realizar tareas para un fin productivo necesariamente. Es difícil medir la calidad del software cuando el objetivo del videojuego es el de hacer sentir bien al jugador. Así que, se propone como posible medida para ello la jugabilidad. Ya hemos mencionado varias veces a lo largo de la memoria este concepto, pero no lo hemos desarrollado en detalle. Como podemos ver en la siguiente figura, extraída de este artículo [47] [48] se agrupan varios parámetros, sensaciones o incluso sentimientos dentro de cinco grandes grupos, de los cuales mencionaremos los tres que más nos interesan.
Implementación 114 Figura 7.1. Parámetros de la jugabilidad • Eficiencia: Si hablamos de eficiencia en el campo de la usabilidad nos estamos refiriendo a realizar el mayor número de acciones correctamente por parte del usuario en el menor tiempo posible, por lo que el periodo de aprendizaje no es precisamente eficiente en ese sentido. Sin embargo, en el campo de la jugabilidad, el autor del artículo relaciona la eficiencia y efectividad con el tiempo y los recursos necesarios para lograr los objetivos propuestos en el videojuego, algo que se relaciona directamente con el aprendizaje. Por tanto, un juego debe ser eficiente en cuanto al aprendizaje. Un buen diseño de videojuego no puede permitir que los usuarios pierdan horas sin aprender a jugar al juego, resulta frustrante y poco atractivo. Hay que buscar un juego sencillo de entender, con reglas marcadas, pero a su vez divertido. • Flexibilidad: Un juego que sea fácilmente accesible a la vez que permita una personalización dentro del juego con la que cada usuario pueda sentirse cómodo hacen que el juego sea flexible y aumente la jugabilidad. Hemos querido que nuestro juego tenga un grado de personalización alto, por ello el usuario puede personalizar prácticamente todo en el juego. Desde el set de habilidades que quiere hasta el color y nombre que quiere que tenga su personaje en partida.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 115 • Satisfacción: Sentimientos como la diversión, el placer y la emoción son los que hacen al usuario disfrutar con el juego. La motivación viene dada por la satisfacción generada con el juego y las ganas de seguir jugando y aprendiendo de él, mejorando. Todo esto hace que el usuario quede satisfecho con el juego. El componente competitivo de nuestro juego es el que le da la emoción y motivación para seguir jugando, unido a la socialización (al ser en red), que potencia las dos anteriores. Hemos querido cumplir con estos atributos en el diseño del videojuego para que acabe teniendo una jugabilidad buena. En el siguiente apartado hablaremos sobre los prototipos que se han ideado para que, mientras que cumple estos tres puntos deseables mencionados, el juego en pantalla apoye y mejore esto, con una usabilidad buena. 7.2. Prototipos A la hora de diseñar la disposición de los elementos en la pantalla, hemos creado varios prototipos de cómo gustaría que quedara el producto final. En cuanto a la apariencia deseable que debería tener la personalización de los AbilitySet, hemos realizado dos prototipos, muy similares. Uno para la parte de personalizar las Skillshot y otro para la de las pasivas. Se muestran en las dos siguientes figuras, respectivamente. Figura 7.2. Prototipo de pantalla de personalización de las skillshots
Implementación 116 Figura 7.3. Prototipo de pantalla de personalización de las pasivas Nos ha parecido una buena decisión en cuanto a la distinta forma de colocar las pasivas y Skillshot elegidas, el hacerlo de la manera exacta en que se hace. La razón es que esa misma disposición es la que van a tener en el juego, cuyo prototipo veremos a continuación, y que al usuario le ayudará a relacionar de una manera más clara qué parte de su juego es el que está editando. Va a saber que cuando esté editando las Skillshot (los circulares) son para las habilidades lanzables, y cuando edite las cuadradas, serán para las habilidades pasivas. En cuanto al prototipo de la pantalla de juego, hemos sido conscientes del limitado tamaño que tenemos al ser un juego en un dispositivo móvil. Por esa razón, hemos decidido investigar y tomar como ejemplo otros videojuegos con temática similar para ver cómo han resuelto el problema. Hemos tenido que encontrar un juego en el que importen el tamaño de los personajes, para que se puedan ver correctamente en pantalla y a su vez que haya varios joysticks que nos permitan lanzar las habilidades. Todo considerando que esto último no nos quite visibilidad del personaje. Este ha sido el motivo principal por el cual se ha decidido que la cámara siga en todo momento al personaje, de manera que quede situado siempre en el centro. El juego principal que nos ha servido de referencia ha sido el Brawl Stars.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 117 Figura 7.4. Partida de Brawl Stars Como podemos ver, utiliza un joystick a la izquierda de la pantalla, que sirve para el movimiento, y otros dos más pequeños en la parte derecha de ésta. También podemos ver el tamaño de los personajes, que es el idóneo para la jugabilidad. En cuanto a esos aspectos, Brawl Stars ha sido de gran ayuda. En cambio, hay otros elementos, contenidos también en el HUD, que el Brawl Stars no nos proporciona. Desde un principio queríamos que el jugador pudiera ver sus estadísticas base, su barra de vida y los PlayerModifier que le están afectando actualmente, aparte de sus Pasivas. Hay un juego que cumple casi al 100% estos requisitos, la única pega es que no es para dispositivo móvil, pero aún así creemos que muestra esa información de una forma tan buena y poco intrusiva en la pantalla de juego que lo hemos querido tomar como referencia. Es el caso del League Of Legends. Figura 7.5. Partida con pantalla completa de League Of Legends
Implementación 118 Figura 7.6. HUD visto con detalle de League Of Legends Como podemos ver en la imagen, este juego nos proporciona los 3 elementos que queríamos incluir en nuestro HUD. Tomaremos en cuenta esta manera de hacerlo para incluirlo a nuestra pantalla de juego, además de añadir las pasivas, cosa que no aparece en el League of Legends, pero creemos que bajo la barra de vida puede ser una buena posición. A continuación, mostramos el prototipo ideado para la pantalla de juego. Figura 7.7. Prototipo detallado de la pantalla de juego También, como podemos observar en ambos juegos, se ha decidido añadir una pequeña barra de vida y un nombre justo encima del jugador, para dar una visión más rápida de la salud de nuestro personaje, tanto para nosotros como jugadores como para el jugador contrario. A continuación, describiremos los elementos de la fase de implementación más destacables.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 119 7.3. Interfaz de usuario fuera de partida En este punto vamos a hablar de la implementación y diseño de la interfaz de usuario fuera de la partida, es decir, de los diversos menús y escenas para personalizar las habilidades y acceder a la partida. La parte visual de estos menús se ha realizado con los elementos UI (User Interface) que nos brinda Unity, como son Canvas (contendor de elementos de UI) e Image (de base son imágenes, pero pueden incorporar componentes para darles más utilidad). Cabe destacar que tanto dentro como fuera de la partida, en cada escena, un GameObject con un sencillo script (en la mayoría de los casos) para gestionar los elementos de UI. Por ejemplo, para volver hacia atrás de una escena a otra, para salir de la partida al Lobby, etc. Estos elementos suelen llamarse como la escena a la que pertenecer con el añadido final de Manager. Nombraremos solamente aquellos elementos que hayan supuesto un costo adicional de implementación, ya que una gran parte de este desarrollo es el trabajo con el editor de Unity y consiste en añadir elementos a la escena, colocarlos y asignarles funciones al recibir eventos. 7.3.1. Personalización AbilitySet Hemos considerado digna de mención esta escena, que, aunque lleva gran parte de edición mediante Unity, también incorpora las funciones por las que el usuario puede editar directamente su AbilitySet. Creemos que esto ayudará a entender la apuesta por la facilidad de aprendizaje a la hora de personalizar elementos dentro del juego. A continuación, mostramos la jerarquía de la escena, esta es la más compleja de todas debido a su elevado número de elementos, pero necesario para explorar y editar todas las posibilidades que debería ofrecernos personalizar un AbilitySet. En esta primera imagen, veremos que dentro de Canvas_AbilitySet tenemos otros 4 Canvas. Figura 7.8. Jerarquía escena AbilitySet
Implementación 120 A continuación, desarrollaremos individualmente el contenido de cada Canvas. • Canvas_Nombre: Este Canvas contiene tres elementos principales. De izquierda a derecha, el botón de volver a “Personalizar”, el nombre del AbilitySet y el botón para guardar de manera permanente los cambios realizados al AbilitySet. Figura 7.9. Elementos de la escena Canvas_Nombre En cuanto al botón de volver, su implementación es similar a la del apartado anterior, pero en vez de regresar al menú principal, regresa al menú inmediatamente anterior, el de Personalizar. Respecto al nombre, al pulsar en él se habilitará un cuadro de texto para introducir el nuevo nombre que queramos ponerle al AbilitySet. El botón de guardar llama a la función del manejador “GuardarCambios” la cual llama a la función en el SQLiteManager para que guarde toda la información. • Canvas_PS: Figura 7.10. Jerarquía Canvas_PS Dentro de este Canvas tenemos 3 principales elementos, los dos primeros y más sencillos son BotonSkillshots y BotonPasivas, después explicaremos el Panel principal. Figura 7.11. BotonSkillshots y BotonPasivas
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 121 La funcionalidad de estos botones se resume en cambiar la apariencia de la escena en general para Skillshots o para Pasivas, según al botón que pulses, desactivará y activará los paneles correspondientes. Con respecto al Panel principal, vemos que contiene, a su vez, dos paneles. El PanelSkillshots contiene imágenes de todos los Skillshots de los que el usuario dispone para seleccionar. El PanelPasivas contiene lo mismo, pero con las Pasivas. Figura 7.12. Interfaz para personalizar las skillshots Figura 7.13. Interfaz para personalizar las pasivas Al pulsar cualquiera de las imágenes (que tiene funcionalidad de botón), la información de ese elemento se cargará en el Canvas_Info, que explicaremos a continuación. Además, ese elemento queda “marcado” o “elegido”, esto es importante para lo que explicaremos en el Canvas_Elegidas.
Implementación 128 • VirtualJoystick de movimiento es un joystick situado a la parte izquierda de la pantalla que permite al usuario mover a su personaje. • VirtualJoystick de habilidades son 3, y son joysticks situados a la parte derecha de la pantalla. Permiten al usuario lanzar las Skillshots que el jugador haya asignado al personaje. Figura 7.19. Vista general del HUD en partida Ahora entraremos a explicar la jerarquía del HUD y su correspondencia con los elementos que hemos mencionado anteriormente. Figura 7.20. Jerarquía del HUD • PlantillaStats simplemente es una imagen con los símbolos de ataque, defensa y velocidad y los recuadros de debajo, dejando libres los cuadros de la derecha para un TextStats (clase para mostrar los atributos de los Players), que
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 129 simplemente es un GameObject con un componente de tipo Text. Se corresponde con estadísticas del jugador. Figura 7.21. Plantilla de las estadísticas • Barra de vida contiene una imagen verde y una imagen como el rectángulo que podemos ver, pero vacío. Al actualizarse con la vida actual, la barra de la imagen verde se va haciendo más pequeña, dejando solo a la vista la parte vacía. El efecto que produce es el siguiente. Figura 7.22. Barra de vida • PlantillaPasivas contiene la imagen con recuadros del fondo y 3 imágenes que se ocuparán con las pasivas elegidas por el jugador. Figura 7.23. Plantilla que aloja las pasivas • PlantillaPlayerModifier contiene varias imágenes que estarán invisibles hasta que, las posiciones del ListPlayerModifiers del Player tenga más de 3 (hasta ahí está reservado para las Pasivas) PlayerModifiers. En ese momento las imágenes de los nuevos PM que vayan afectando al jugador se irán mostrando, ocupando las imágenes hasta entonces invisibles. • JoystickBackgroundImage contiene un script de tipo VirtualJoystick, el encargado de calcular el movimiento que va a realizar el personaje según donde se coloque el puntero (otra imagen, pero más pequeña).
Implementación 130 Figura 7.24. Joystick de movimiento en acción • Canvas_Skillshots es un Canvas que contiene los 3 JoystickSkillshotBackgroundImage pertenecientes a cada uno de los 3 Skillshots que va a poder utilizar el usuario durante la partida. En cuanto a composición en jerarquía además de lo mencionado en el joystick de movimiento disponen de una imagen para mostrar a qué Skillshot pertenece cada joystick. Figura 7.25. Joystick de habilidades en acción Una vez vistos todos los componentes y su importancia de cara a la información que tiene que recibir el usuario, pasaremos a explicar las funciones más importantes dentro del script HUD. Una de las cosas más importantes dentro del script es la “recogida” correcta de todos los elementos creados desde el editor en el script, todo con ayuda del comando Find, explicado en la parte de diseño. Una vez todos los elementos relevantes de la escena tienen su objeto en el script, simplemente las funciones son ActualizaImagenesPlayerModifiers, ActualizarStats,
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 131 ActualizarImagenesPasivas, ActualizarVida y ActualizarSkillshots. Como sus nombres indican, las funciones se encargan de ir rellenando correctamente los elementos descritos en el HUD. Como mención importante a parte de estas funciones tenemos UpdateHUD y SoftUpdateHUD. Básicamente lo que hacen estas funciones es ejecutar las primeras funciones nombradas, con la diferencia de que UpdateHUD ejecuta todas y SoftUpdateHUD solo ejecuta las que suelen cambiar más a menudo. El motivo de esto vuelve a ser la optimización. Hay alguna función que requiere acceso a archivos, como es el caso de ActualizaSkillshots que muy rara vez va a ser llamado, excepto al empezar la partida. En cambio, algunas otras como ActualizarStats y ActualizarVida sí van a cambiar muy a menudo, de ahí el separarlo en dos funciones distintas. 7.4.3. SkillshotProjectile Es otro de los elementos más importante de la partida, ya que es la manera principal que tienen para interactuar unos personajes con otros y ganar la partida. El lanzamiento de la habilidad está representado por la clase SkillshotProjectile, y conformado como Prefab con el mismo nombre. No tiene jerarquía, está conformado por solo un GameObject y en cuanto a sus componentes tiene exactamente los mismos y por los mismos motivos que Player, con la salvedad de que el script en este caso es el de SkillshotProjectile. La vida útil del SkillshotProjectile se entiende desde que sale de la ubicación del Player que la lanza hasta que, o bien impacta en un contrario y bien agota su distancia de recorrido (conocido como rango), que desaparece. La función más importante de esta clase se mencionará en el apartado de red, la siguiente función es importante a nivel gráfico del videojuego. • GetRotacionByDirection nos devuelve el ángulo de rotación que tiene que tener ese Skillshot dependiendo de su dirección, de manera que favorezca a una coherencia visual y una experiencia de juego más real. Figura 7.26. Representación del seno y coseno Fuente: [49]
Implementación 132 Suponiendo el eje x (dirección horizontal) como el cos(α) y el eje y (dirección vertical) como sen(α), para hallar el ángulo α que necesitamos para calcular la rotación, hallaríamos la tangente diviendo el sen/cos y después aplicándole la función Mathf.Atan(tangente) hallaríamos el ángulo deseado. Para que la rotación sea siempre la misma vamos a procurar todas las animaciones de las SkillshotProjectile orientadas hacia la derecha, para que la función y cálculo de la rotación sea válido para todas ellas, como vemos en estos ejemplos: Figura 7.27. Orientación inicial que deben tener todas las SkillshotProjectile En cuanto a cómo se instancian estos elementos en el juego en red, será el VirtualJoystickSkillshot el encargado de empezar las llamadas pertinentes para que sea lanzado, cuando detecte en su función OnPointerUp que su cursor o puntero ha sido movido hacia algún lado del joystick y posteriormente se ha soltado, gesto que el usuario tiene que hacer si quiere lanzar la habilidad. 7.4.4. Items Los items, u objetos, son elementos, que, aunque no sean vitales para el desarrollo normal de la partida, sí le añaden un poco más de interactividad y amplían las posibilidades dentro de una partida. Como los mencionados anteriormente también son Prefab, ya que a lo largo de la partida habrá varios de estos elementos apareciéndose de forma aleatoria en el campo de batalla. Este comportamiento es el que se va a tratar de realizar gracias a las funciones que describiremos a continuación. En cuanto a la jerarquía no posee nada más. Y en componentes, son exactamente los mismos que Skillshot y Player. Como mencionamos en el apartado de diseño, ítem es la clase con los métodos pero el “envoltorio” para que pueda funcionar en la partida es ItemInstance. Las funciones relevantes son: • GetItemPlayerModifier que devuelve el PlayerModifier asignado al Item en cuestión. • CatchItemSimple que hace desaparecer al Item, una vez hemos recogido anteriormente su PlayerModifier. Y hasta aquí los Prefabs importantes para la partida y la implementación de sus scripts. A continuación, hablaremos de otras características muy importantes
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 133 también para el videojuego, como animaciones, comandos especiales de red y entrar a explicar cómo funciona el movimiento con los VirtualJoysticks. 7.4.5. Animaciones Las animaciones que se tienen en la escena se gestionan principalmente con el componente Animator. Este componente hace uso de un AnimatorController, el cual describe un comportamiento, en forma de máquinas de estados. Según determinadas variables que nosotros indicaremos, el controlador hará que el GameObject pase por un estado o por otro, reproduciendo en el estado en el que esté la animación correspondiente. Para crear las animaciones en 2D basta con conseguir un pequeño grupo de imágenes, que unidas secuencialmente como si de un GIF se tratase, simulen el movimiento del GameObject, por ejemplo, aquí podemos ver las de una SkillshotProjectile. Figura 7.28. Ejemplo animación de SkillshotProjectile Aunque muy parecidas, las imágenes son un poco distintas y gracias a eso, cuando se reproducen de forma secuencial, da la impresión de que la bola de fuego está en continuo cambio mientras viaja por el campo de batalla. Algunas de estas imágenes han sido adquiridas mediante licencias Creative Commons, otras han sido dibujadas por el equipo de desarrollo. A continuación, mostraremos el AnimatorController del Player para explicar cómo funciona. Figura 7.29. PlayerController, el AnimatorController de Player
Implementación 134 Como podemos ver, el AnimatorController consiste en una máquina de estados, la cual empieza en un estado base, que será cuando el Player esté ocioso, sin movimiento ni ataque. Si nos fijamos en la parte izquierda de la imagen, hay unas algunas variables. Éstas en concreto se denominan Triggers. Desde los scripts podemos desencadenar estos triggers, eso lo escucha el Controller y activa ese Trigger. Como vemos desde Any State, podemos ir a cualquiera de los otros estados. Lo que necesita para ir de uno a otro se denomina transición. Veamos a fondo qué es una transición. Figura 7.30. Ejemplo de transición de Player Una transición representa tanto las condiciones como la forma en la que pasar de un estado a otro. Como podemos ver, ésta va de AnyState, es decir, de cualquier otro estado, hasta PlayerUp. En la configuración tenemos varios parámetros para adecuar la transición a nuestro gusto. Por ejemplo, si queremos que la transición dure más o menos, que sea inmediata, que tenga algún tipo de retardo, etc. Por último, vemos que tiene “Condiciones” para que esta transición se ejecute. La única y simple condición de esta transición es que el trigger “playerUp” sea lanzado. Como decíamos antes, los triggers se pueden desencadenar desde los scripts, en este caso concreto, desde el script de Player, en el momento previo a realizar un movimiento, calculando la dirección que el Player va a tomar, ejecutamos un
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 135 trigger u otro, para darle al personaje la animación coherente con la dirección que éste va a tomar. 7.4.6. Movimiento En este punto volvemos a hablar de programación, concretamente de cómo funciona el movimiento tanto del personaje como de los lanzamientos de habilidades. Lo primero que debemos saber es que ambas clases heredan de una abstracta llamada MovingObject (Objeto Movible). Éste describe el comportamiento que debe tener un objeto que quiera moverse por el terreno, con qué velocidad y qué hacer cuando se topa con otros elementos. En cuanto a las funciones implementadas, las más notables son AttemptMove, SimpleMove y OnCantMove, ésta última es abstracta y cada clase heredada debe implementarla de la manera que considere. Las dos primeras básicamente van comprobando colisiones (con ayuda de Box Collider 2D) y si el objeto puede ir moviéndose en la dirección indicada o si, por el contrario, no puede, que llamaría a OnCantMove. Ahora veamos cómo el usuario puede incidir en el movimiento, llega el turno de explicar los VirtualJoystick. Vamos a comenzar explicando la clase VirtualJoystick. Solamente dispone de un atributo, a parte de las imágenes, que son GameObjects. El atributo es de tipo Vector3, una clase usada para el manejo de vectores, y su nombre es inputVector, su cometido es guardar el vector que se está describiendo con el puntero. Es una clase que hereda de IDragHandler, IPointerUpHandler y IPointerDownHandler, los cuales son necesarios para el manejo de lo que va a ser nuestro puntero del joystick. Esta herencia nos permite usar los siguientes métodos. • OnDrag toma la posición del puntero con respecto a la posición de la imagen de fondo para saber qué dirección se está queriendo describir. Teniendo eso, actualiza los valores de inputVector, indicándole los valores correspondientes en los ejes x e y. • OnPointerDown se usa para describir qué se debe hacer cuando se ha pulsado el puntero, esta función llama directamente a OnDrag. • OnPointerUp se usa para describir qué se debe hacer cuando se ha soltado el puntero de la pantalla. Lo que hace es devolver el inputVector a los valores del vector 0, además de mover la imagen del puntero al centro, donde empezó. Después de estas funciones, que son heredadas y han sido sobrescritas, nuestro VirtualJoystick tiene dos funciones para consultar cómo está el inputVector en
Implementación 136 un instante determinado. Estas funciones se llaman Horizontal y Vertical. Su función consiste simplemente en devolver el valor de su eje correspondiente. Estas funciones son las únicas usadas por parte del Player a la hora de moverse, así calcula la dirección a la que el joystick le indica. Es el turno de VirtualJoystickSkillshot. Esta clase hereda de VirtualJoystick, por lo que conserva la mayor parte de su implementación. Una de las diferencias, la más importante es la variación a la función OnPointerUp. La variación consiste en que, en el momento que se suelta el puntero, en esa dirección en concreto, es cuando debería lanzarse la SkillshotProjectile, y justo después de que esto suceda, realizar el código del padre, como si de un VirtualJoystick normal se tratase. Una vez tenemos esa dirección capturada en el inputVector, ya sabemos que esa es la que tiene que tener la SkillshotProjectile en su viaje por el campo, así que recogemos con Horizontal y Vertical y la enviamos a Player para que genere la SkillshotProjectile correctamente. Otra diferencia es que este joystick tiene una Skillshot asociada y su imagen se puede ver en el propio joystick, como vimos en la explicación de los componentes del HUD. 7.5. Gestión de las funcionalidades de red Llegados a este punto, toca hablar sobre las funcionalidades de red que nos brinda NetworkBehaviour [50]. Antes de nada, vamos a explicar cómo realiza UNET [51] las acciones a través de la red. Estas acciones se conocen como Llamadas a Procedimiento Remoto (Remote Procedure Calls o RPC). Hay dos tipos, los Comandos (Commands) que son llamados desde el cliente al servidor y las llamadas ClientRPC, que son llamadas en el servidor y ejecutadas en el cliente.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 137 Figura 7.31. Flujo de acciones Cliente-Servidor UNET En el diagrama anterior podemos identificar y diferenciar 4 elementos principales: • El Input, que representa el “manejador” del cliente con su Player (que se encuentra en el servidor). • El Player que es la instancia del personaje jugable del usuario en el servidor. • Los Objetos de Servidor son las representaciones de los objetos que se encuentran en el servidor, una instancia de ellos. • Los Objetos de Cliente son instancias copiadas de la instancia del servidor. Esta copia se realiza mediante el método Spawn(gameObject), siendo gameObject el objeto que se encuentra en el servidor que queremos que aparezca en todos los clientes. Como podemos ver, los comandos son llamadas por parte del cliente al servidor. Hacemos esto porque queremos que en el servidor se ejecute algo en concreto, lo veremos más adelante con detalle y ejemplos. Por otro lado, si nos fijamos en los mensajes que van a de los objetos de servidor a los objetos de cliente, podemos observar, por ejemplo, ObjectSpawn, que sería lo mencionado anteriormente con el método Spawn, y ObjectDestroy, el cual es llamado cuando el objeto en el servidor es destruido, para que los de los clientes se destruyan también, manteniendo la consistencia en el juego. El resto de las llamadas las explicaremos más adelante.
Implementación 144 • InsertarSkillshot, inserta un Skillshot en la base de datos. • InsertarItem, inserta un Item en la base de datos. • GetPlayerModifier, indicando un índice, el idPlayerModifier, devuelve el PlayerModifier, con sus arrays de SimpleModifiers pertinentes. • GetSkillshot, indicando un índice, el idSkillshot, devuelve el Skillshot y su PlayerModifier, si lo tuviera. • GetAbilitySets, indicando un User, devuelve todos los AbilitySet que posee el usuario. • DarAltaUser, indicando un User, crea el User y también la estructura del UserAbilitySet, con sus tres AbilitySet pertinentes. • UserAndUserAbilitySetExist confirma, consultando un User, si ya existe, y si es así, también existe su UserAbilitySet. Además de estas funciones, hay varias más dedicadas a la inicialización de las tablas, la limpieza total de las tablas y comprobar si las tablas están creadas. Son útiles para comprobar si las tablas ya han sido creadas y rellenadas con anterioridad, o por el contrario es la primera vez que se accede y hay que hacerlo, así como si el usuario está creado o no, y si no, darlo de alta. Todas estas gestiones se realizan desde una clase llamada InicializarValoresBD, que centraliza esta gestión, además de crear en ella los PlayerModifiers, Skillshots e Items que van a usarse en la partida. 7.7. Recursos utilizados A la hora de crear un videojuego, como comentábamos al principio del capítulo, no basta con la programación de código. Ya vimos la parte relacionada con el editor de Unity creando y colocando los elementos de la escena, también vimos las animaciones. Pero hay elementos que ayudan a que el juego sea más vistoso, más agradable a la vista. Es el trabajo de los artistas y diseñadores gráficos. A menudo, estos brindan a la comunidad de desarrolladores sus creaciones bajo distintos tipos de licencias. Propiamente, en la misma tienda de Assets de Unity, podemos adquirir muchos elementos de este tipo. A continuación, haremos mención a los elementos que hemos adquirido y que ahora forman parte de nuestro proyecto.
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 145 7.7.1. Recursos adquiridos de la Asset Store de Unity La Asset Store de Unity tiene multitud de elementos que puedes incorporar a tu proyecto, algunos incluso de forma gratuita. En nuestro caso, hemos adquirido los siguientes. • NetworkLobby, compuesto por una serie de GameObject y clases que realizan las funciones de un Lobby. Permite al desarrollador que opte por incluir este asset en su proyecto, entrar en su código y modificarlo si se considera necesario. También proporciona la escena preparada con todos sus elementos de UI. Obviamente, esto también es personalizable. Figura 7.37. NetworkLobby En el caso de este proyecto, se realizó la funcionalidad en red completa apoyándose en un sistema de emparejamiento poco elegante. Era un sistema que usaba una clase que pertenece a la API de Unity llamada NetworkManager. Esta permite conectar a varios jugadores a disputar una partida mientras uno de ellos aloja la partida. Decimos que es poco elegante porque para poder conectarse a una partida, era necesario escribir de forma manual la IP del jugador que alojaba la partida cada vez que se quería jugar. Una vez finalizada la funcionalidad completa y se comprobó, mediante las pruebas que veremos en el apartado correspondiente, que el juego funcionaba con normalidad, se decidió mejorar ese aspecto que nos parecía poco elegante. Por lo que se decidió pasar de ese sistema de emparejamiento a uno que, a ser posible, tuviera una manera más atractiva de interconectar a los usuarios. Así se descubrió este asset y se decidió iniciar la incorporación de él en nuestro proyecto.
Implementación 146 Fue necesario informarse previamente sobre su funcionamiento, las clases que lo componían y cómo interactuaban entre sí, además de cómo tenían que interactuar con los elementos que ya funcionaban en nuestro juego. Después de algunos ajustes, tanto en el asset como en nuestras clases y escenas, y de la repetición de las pruebas, se pasó de la versión antigua a la actual, con el nuevo Lobby funcionando correctamente. Enlace: https://assetstore.unity.com/packages/essentials/network-lobby-41836 • Imágenes temáticas de distintos alimentos y bebidas, al estilo Pixel Art, para dar vida a los items que van a ir apareciendo en el suelo. Figura 7.38. Pixel Food Enlace: https://assetstore.unity.com/packages/2d/environments/free-pixel-food-113523 7.7.2. Recursos adquiridos de distintos creadores No solo de la Asset Store de Unity podemos conseguir elementos que incorporar a nuestro videojuego. Hay multitud de portales en los que la comunidad comparte sus diseños. Algunos de estos se ven sometidos a licencias, que cada autor indica en la página en la que puedes conseguir su aportación. Así pues, vamos a darle el crédito que se merecen a los creadores del contenido que hemos usado, bien para incluir tal cual o bien para modificarlo nosotros mismos y posteriormente incluirlo. • Avatar para jugar la partida. Se buscaba un personaje, preferiblemente con aspecto de guerrero con espada, en 2D y con 8 direcciones. Se escogió finalmente este, que se ajustaba bastante bien a lo requerido. Enlace: https://www.spriters-resource.com/sharp_x68000/thereturnofishtar/sheet/112403/
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 147 • Fuente Pixelade es la fuente que hemos utilizado para la mayoría de los menús y avisos dentro de la pantalla. Se buscaba una fuente con estilo pixel y esta es la idónea. Figura 7.39. Fuente Pixelade Enlace: https://www.dafont.com/es/pixelade.font • Imágenes para los Skillshot y los Player Modifiers. Se requerían imágenes, con un aspecto no demasiado moderno, que representaran ciertas situaciones mágicas o de guerra. Hay un conocido juego de cartas, Yu-gi-oh!, el cual contiene muchas de esas situaciones y pensamos que podían quedar muy bien para estos dos cometidos. Enlace: https://www.spriters-resource.com/game_boy_advance/ygoeternalduelsoul/sheet/40049/ • Imágenes para los menús y HUD. Necesitábamos imágenes que nos pudieran servir, al menos como base, para realizar el HUD deseado y los menús acordes a la temática 2D pixel art. Encontramos la siguiente figura, y nos pareció que encajaba mucho con lo que queríamos. Figura 7.40. Imagen utilizada como base para el HUD
Implementación 148 Con respecto a esto, ha sido donde más hemos tenido que utilizar GIMP, la herramienta de edición. Usando como base esta imagen hemos podido editar hasta realizar los menús, los joysticks, botones y el resto de los elementos para que quedaran a nuestro gusto. Enlace: https://opengameart.org/content/ui-pieces • Sprites para las SkillshotProjectile. Necesitábamos varios Sprite o imágenes para realizar las animaciones que iban a acompañar a las SkillshotProjectile reproduciéndose en bucle durante todo su viaje por el campo de batalla. Estos son los que hemos usado, el resto han sido derivados de alguno de estos o bien creados totalmente de cero. Enlaces: https://opengameart.org/content/rotating-arrow-projectile (flecha normal) https://opengameart.org/content/firebal-32x32 (bola de fuego) https://opengameart.org/content/scimitar-sword (espada cuerpo a cuerpo)
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 149 8. Pruebas En un desarrollo de software pueden aparecer errores en cualquier momento de su ciclo de vida, algunos de ellos puede que nunca se hayan materializado pero que permanezcan ocultos. Para evitar que, el día de mañana, nuestro desarrollo no sea defectuoso, es recomendable la realización de pruebas a lo largo de todo el proyecto. En este capítulo presentaremos las pruebas realizadas como parte de la fase de transición del proyecto. El tipo de prueba elegido será caja negra. En cada prueba podremos ver los resultados obtenidos, así como las correcciones necesarias en caso de la ocurrencia de un fallo. Vamos a organizar las pruebas en dos grandes grupos. 8.1. Pruebas unitarias Son las pruebas que confirman el correcto funcionamiento de un bloque de código en concreto. Al ser un videojuego, la mayor parte de las comprobaciones engloban varios casos de uso de una forma inevitable, ya que se tienen que realizar de forma manual, a través de eventos que provengan del usuario. Aun así, vamos a intentar separar las pruebas para que sean lo más unitarias posible, de manera que se asemejen a pequeñas situaciones que se deben cumplir en el juego. Dividiremos las pruebas en pruebas fuera de partida y dentro de la partida.
Pruebas 150 8.1.1. Pruebas unitarias fuera de la partida 8.1.1.1. Identificarse PCN-001 Identificación correcta sin usuario creado previamente Descripción El usuario se identifica en el sistema sin tener previamente ese nombre registrado en el dispositivo. Resultado esperado Se crea un nuevo usuario y el usuario queda identificado. Fase de aplicación Fase final Valoración OK Tabla 8.1. PCN-001. Identificación correcta sin usuario creado previamente PCN-002 Identificación correcta con usuario creado previamente Descripción El usuario se identifica en el sistema teniendo previamente un usuario registrado en el dispositivo. Resultado esperado El sistema recupera de base de datos toda la información del usuario y éste queda identificado. Fase de aplicación Fase final Valoración OK Tabla 8.2. PCN-002. Identificación correcta con usuario creado previamente
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 151 8.1.1.2. Personalizar PCN-003 Entrar correctamente al menú de Personalizar Descripción El usuario entra en Personalizar, pulsando su botón en el menú. Resultado esperado Al cargarse la nueva escena, aparecen correctamente sus AbilitySet con sus nombres y el seleccionado favorito correctamente. Fase de aplicación Fase final Valoración OK Tabla 8.3. PCN-003. Entrar correctamente al menú de Personalizar PCN-004 Seleccionar un AbilitySet como favorito Descripción El usuario pulsa en el botón de la estrella del AbilitySet que desee hacer su favorito. Resultado esperado La estrella pulsada cambia a amarillo y la anterior favorita pasa a estar vacía. Fase de aplicación Fase final Valoración OK Tabla 8.4. PCN-004. Seleccionar un AbilitySet como favorito PCN-005 Entrar a editar un AbilitySet Descripción El usuario pulsa en un AbilitySet para editarlo. Resultado esperado La nueva escena carga todas las Skillshot y Pasivas disponibles para el usuario, además de las que ya tenía guardadas en ese AbilitySet. Fase de aplicación Fase final Valoración OK Tabla 8.5. PCN-005. Entrar a editar un AbilitySet
Pruebas 152 PCN-006 Seleccionar una Skillshot Descripción El usuario pulsa en una Skillshot. Resultado esperado La información de la Skillshot se carga en el panel de información. Fase de aplicación Fase final Valoración OK Tabla 8.6. PCN-006. Seleccionar una Skillshot PCN-007 Seleccionar una Pasiva Descripción El usuario pulsa en una Pasiva. Resultado esperado La información de la Pasiva se carga en el panel de información. Fase de aplicación Fase final Valoración OK Tabla 8.7. Seleccionar una Pasiva PCN-008 Cambiar Skillshot/Pasiva del AbilitySet por la seleccionada Descripción El usuario pulsa en la ranura de Skillshot/Pasiva que desee, previamente de tener una seleccionada en el panel de información. Resultado esperado La ranura pasa a tener la imagen de la Skillshot/Pasiva elegida. Fase de aplicación Fase final Valoración OK Tabla 8.8. PCN-008. Cambiar Skillshot/Pasiva del AbilitySet por la seleccionada
Estudio y aplicación de un juego en red multijugador para dispositivos móviles 153 PCN-009 Cambiar el nombre del AbilitySet Descripción El usuario pulsa en el AbilitySet e introduce el nuevo nombre. Resultado esperado El nombre del AbilitySet cambia correctamente. Fase de aplicación Fase final. Valoración OK Tabla 8.9. PCN-009. Cambiar el nombre del AbilitySet PCN-010 Guardar toda la información cambiada Descripción El usuario pulsa el botón de guardar después de haber realizado cambios. Resultado esperado Los nuevos cambios quedan reflejados en la base de datos. Fase de aplicación Fase de desarrollo. Valoración Incorrecto. Hubo unos problemas con la base de datos relativos a que había errores en la sintaxis de SQLite. Después de varias depuraciones se consiguió que toda la sintaxis fuera la adecuada y todo funcionara correctamente. Tabla 8.10. PCN-010. Guardar toda la información cambiada PCN-011 Guardar toda la información cambiada Descripción El usuario pulsa el botón de guardar después de haber realizado cambios. Resultado esperado Los nuevos cambios quedan reflejados en la base de datos. Fase de aplicación Fase final Valoración OK Tabla 8.11. PCN-011. Guardar toda la información cambiada