Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Memoria TFG
Memoria TFG
de
Ciencias
Febrero – 2019
1
2
Índice de contenido
Agradecimientos ........................................................................................................... 8
Resumen ...................................................................................................................... 9
Abstract ...................................................................................................................... 10
1. Introducción ............................................................................................................ 11
1.1 Estado del Arte .................................................................................................. 11
1.2 Motivación ......................................................................................................... 13
1.3 Objetivo ............................................................................................................. 13
2. Herramientas, tecnologías y materiales utilizados .................................................. 14
2.1 Herramientas ..................................................................................................... 14
2.1.1 Unity ........................................................................................................... 14
2.1.1.1 Interfaz de Unity ................................................................................... 15
2.1.2 MonoDevelop .............................................................................................. 16
2.1.3 Adobe Illustrator CS6 .................................................................................. 16
2.1.4 Tiled Map Editor .......................................................................................... 16
2.2 Tecnologías ....................................................................................................... 17
2.2.1 C# ............................................................................................................... 17
2.2.2 Photon Engine ............................................................................................ 17
2.2.3 XML ............................................................................................................ 19
2.2.4 Librerías de Unity ........................................................................................ 19
2.2.5 Android SDK ............................................................................................... 20
2.3 Materiales.......................................................................................................... 20
3. Metodología ............................................................................................................ 21
3.1 Metodología iterativa incremental ...................................................................... 21
3.2 Planificación ...................................................................................................... 22
3.2.1 Etapa de formación ..................................................................................... 22
3.2.2 Etapa de desarrollo ..................................................................................... 23
3.2.3 Etapa de integración ................................................................................... 24
3.2.4 Funcionalidades por iteración ..................................................................... 24
3.2.4.1 Iteración 1 ............................................................................................ 24
3.2.4.2 Iteración 2 ............................................................................................ 24
3.2.4.3 Iteración 3 ............................................................................................ 24
3.2.4.4 Iteración 4 ............................................................................................ 25
3.2.4.5 Iteración 5 ............................................................................................ 25
3.2.4.6 Iteración 6 ............................................................................................ 25
3.2.4.7 Iteración 7 ............................................................................................ 25
3.2.4.8 Iteración 8 ............................................................................................ 25
3.2.4.9 Iteración 9 ............................................................................................ 26
3.2.4.10 Iteración 10......................................................................................... 26
4. Análisis de requisitos .............................................................................................. 26
4.1 Requisitos funcionales....................................................................................... 26
4.2 Requisitos no funcionales .................................................................................. 27
5. Diseño e Implementación........................................................................................ 28
5.1 Arquitectura del sistema .................................................................................... 28
5.2 Capa de presentación ....................................................................................... 30
5.2.1 Interfaz de usuario ...................................................................................... 30
5.2.1.1 Interfaz del juego .................................................................................. 30
5.2.1.2 Interfaz de menús ................................................................................. 34
5.2.2 Escenas ...................................................................................................... 35
5.3 Capa de negocio ............................................................................................... 36
5.3.1 Estructura del proyecto ............................................................................... 36
5.3.2 Game Manager ........................................................................................... 38
5.3.3 Tablero ....................................................................................................... 40
5.3.4 Servidor Photon .......................................................................................... 40
3
5.3.5 Sumario ...................................................................................................... 42
5.4 Capa de datos ................................................................................................... 44
5.4.1 Ficheros XML .............................................................................................. 44
5.4.2 Ficheros csv................................................................................................ 46
5.4.3 Clasificación................................................................................................ 47
6. Evaluación y Pruebas ............................................................................................. 48
6.1 Pruebas unitarias y de integración ................................................................. 48
6.2 Pruebas de sistema ....................................................................................... 50
6.2.1 Pruebas de portabilidad ........................................................................... 50
6.2.2 Pruebas de compatibilidad ...................................................................... 50
6.2.3 Pruebas de rendimiento .......................................................................... 50
6.3 Pruebas de aceptación .................................................................................. 52
7. Conclusiones y trabajos futuros .............................................................................. 53
7.1 Conclusiones ..................................................................................................... 53
7.2 Trabajos futuros ................................................................................................ 53
8. Referencias............................................................................................................. 54
4
Índice de figuras
Figura 1 – Dragon Box Elements ................................................................................ 12
Figura 2 – Interfaz Unity.............................................................................................. 15
Figura 3 – Servidor Photon ......................................................................................... 18
Figura 4 – Analizador de rendimiento ......................................................................... 19
Figura 5 – Esquema iterativo incremental ................................................................... 21
Figura 6 – Retarded Bird............................................................................................. 23
Figura 7 – Arquitectura en tres capas ......................................................................... 29
Figura 8 – Tablero físico ............................................................................................. 30
Figura 9 – Interfaz usuario del juego digital................................................................. 31
Figura 10 – Reporte de actuación ............................................................................... 32
Figura 11 – Formulario de plan de proyecto ................................................................ 32
Figura 12 – Ventana modal de reconfiguración ........................................................... 33
Figura 13 – Paleta colores de la interfaz ..................................................................... 33
Figura 14 – Mockup del menú principal....................................................................... 34
Figura 15 – Mockup lobby ........................................................................................... 35
Figura 16 – Mockup sala ............................................................................................. 35
Figura 17 – Segundo tablero....................................................................................... 40
Figura 18 – Sumario del juego .................................................................................... 43
Figura 19 – Diagrama UML de la herencia de Riesgo ................................................. 46
Figura 20 – Clasificación en dreamlo .......................................................................... 47
Figura 21 – Unity Profiler ............................................................................................ 51
Figura 22 – Información de uso de memoria ............................................................... 51
Figura 23 – Información de uso de CPU ..................................................................... 52
5
Índice de tablas
Tabla 1 – Planning del proyecto .................................................................................. 22
Tabla 2 – Requisitos funcionales ................................................................................ 27
Tabla 3 – Requisitos no funcionales ........................................................................... 28
Tabla 4 – Jerarquía de scripts desarrollados .............................................................. 37
6
Índice de código
Código 1 – Patrón Singleton (GameManager.cs) ........................................................ 38
Código 2 – Método TirarDado (GameManager.cs) ..................................................... 39
Código 4 – LobbyNetwork.cs ...................................................................................... 41
Código 5 – Fragmento de PlayerNetwork.cs ............................................................... 41
Código 6 – DDOL.cs ................................................................................................... 42
Código 7 – Actualización de puntuaciones.................................................................. 43
Código 8 – ContenedorEmpleado.cs .......................................................................... 45
Código 9 – Estructura del XML de empleados ............................................................ 45
Código 3 – Fichero .csv del tablero ............................................................................. 46
Código 10 – Prueba Test Runner................................................................................ 49
7
Agradecimientos
Primeramente, quiero darle las gracias a mi familia, sobre todo a mis abuelos, por
creer en mí, por apoyarme en todo momento y por animarme al grito de “Tú puedes
con todo”. Si soy lo que soy se lo debo a ellos más que a nadie. Lo único que les
puedo reprochar es que querían un médico en la familia. Lo siento.
Especial mención también a mis hermanas, Paula y Lucía. Lo nuestro es una montaña
rusa de emociones, a veces les quiero y a veces les odio pero son lo mejor de este
mundo. También quiero darle las gracias a mi padre, allá donde estés, se que estarás
orgulloso. Ha pasado mucho tiempo, pero te sigo teniendo presente.
A mis amigos de toda la vida, Kevin y Aaron, por escuchar mis problemas e intentar
comprenderme. Por darme los mejores consejos y sacarme siempre una sonrisa.
Porque desde pequeños no nos hemos separado y estoy convencido, sin miedo a
equivocarme, que estarán siempre que los necesite, lo mismo que yo para ellos.
Gracias a mis compañeros de clase de la universidad, a toda esa gente de bien con
los que me he divertido y he pasado estos buenos años. Con algunos incluso he
viajado. Quizás con muchos no vuelva a hablar, por distancia o simplemente pérdida
de contacto, pero espero que les vaya bien donde quiera que estén.
Por último y no menos importante, muchas gracias a todos los profesores de la carrera
porque, además de ser grandes docentes, de todos ellos he aprendido algo, que ya es
bastante. Quisiera darle gracias sobre todo a Carlos, al que considero ya un amigo,
por sembrar en mi la curiosidad sobre este mundo que es el desarrollo de videojuegos,
por ayudarme en todo lo que he necesitado, pero sobre todo por creer en mi al
ofrecerme este proyecto tan ambicioso.
Un mensaje también para todas las personas que puedan estar leyendo este
documento. Gracias por leerme y espero que podáis encontrar en él algo. Ayuda,
información relevante o mera curiosidad.
8
Resumen
9
Abstract
On the other hand, we find the videogame industry. A market in fervent growing that
seems to have no barriers. With registered earnings, last year, of 108.4 billion dollars
worldwide and millions of players distributed all over the planet.
Linking the importance of project management with the popularity of video games is the
key for this project. In it what is intended is to give a digital format to known board
game called Deliver about management of software projects and in the same time,
introduce improvements on it.
10
1. Introducción
Actualmente, el uso de los juegos serios ha crecido sobre todo en sectores como la
educación, la defensa, la aeronáutica y la salud. Una de sus principales ventajas es
que la funcionalidad que enseñan puede ser de lo más variada: desde entrenar pilotos,
la capacitación de un equipo de ventas o la enseñanza de idiomas, por poner algunos
ejemplos.
11
· Feedback inmediato: A diferencia de las clases donde hay muchos alumnos y un
sólo profesor para resolver dudas, por ejemplo, los juegos serios ofrecen una
retroalimentación inmediata. El jugador interactúa directamente con el juego y recibe
información, una recompensa o incluso un castigo al instante.
· Simulación: En la mayoría de los casos, los juegos serios simulan situaciones que
podrían darse en la vida real. Todo esto a través de la recreación de ambientes o la
creación de personajes.
En la figura 1 se puede ver la pantalla de uno de los niveles del juego Dragon Box
Elements que es un juego serio cuyo objetivo es la construcción de un ejército para
derrotar al malvado dragón Osgard y salvar a la isla de Euclides. Este juego está
pensado para niños y lo que busca es que los pequeños aprendan las bases de la
geometría euclídea. El juego permite a los jugadores aprender matemáticas mientras
se divierten jugando.
12
1.2 Motivación
Como motivación personal está el demostrarme a mí mismo que puedo hacer un juego
completo; sólo y en un tiempo no muy largo. Para trabajar más adelante con otras
herramientas de desarrollo de videojuegos disponibles en el mercado como Unreal
Engine e incluso con lenguajes en los que no se he sido instruido como C++. También
me ayudará, este desarrollo, a fomentar mi interés en aprender más sobre diseño
gráfico. En definitiva, lo que busco es desarrollar un primer juego que me permita
aprender un motor de videojuegos y que me abra la puerta a aprender muchos más.
1.3 Objetivo
Este juego tiene algunos inconvenientes al aplicarse en clase como el rígido uso de los
materiales del juego (tarjetas, fichas, dado…), la necesidad de disponer de dichos
materiales y un lugar para desplegar el juego o que todos los jugadores tengan que
estar alrededor del mismo tablero.
Como objetivo principal se plantea hacer una versión digital del juego Deliver, un juego
serio, que traslade el juego original de tablero a una versión digital y además
introduzca mejoras que permitan un mejor uso en las aulas. Algunos ejemplos de
estas mejoras son: variedad en los tableros, variedad de fichas de recursos, distintas
configuraciones de las reglas de una partida, multidispositivo y multijugador entre
distintos tipos de dispositivos.
13
2. Herramientas, tecnologías y materiales utilizados
Este apartado tiene como objetivo comentar las herramientas, tecnologías y materiales
involucrados durante el desarrollo del proyecto, y ofrecer una visión inicial del trabajo
realizado.
2.1 Herramientas
2.1.1 Unity
Esta herramienta puede ser empleada tanto para crear juegos en dos dimensiones
como en tres dimensiones. También tiene otros usos como la creación de aplicaciones
de realidad virtual y realidad aumenta da o el desarrollo de aplicaciones móviles para
numerosas plataformas.
Actualmente Unity cuenta con cuatro tipos de licencias para aquellas personas que
quieran hacer uso del motor: licencia Personal, licencia Plus, licencia Pro y licencia
Enterprise. Para la realización del proyecto se ha empleado la licencia Personal
porque es la única gratuita. Esta licencia establece varios parámetros como el límite de
beneficio económico que se puede recibir por la aplicación (100.000$) o el número
máximo de usuarios concurrentes en un juego multijugador (20 usuarios). Como es
obvio, a medida que se usa una licencia de mayor rango, Unity ofrece mejores
funcionalidades, aunque también recibe un beneficio económico mayor que deberá
abonar el desarrollador.
14
2.1.1.1 Interfaz de Unity
15
Por último, encontramos el elemento número 7 que correspondiente a la jerarquía de
archivos del proyecto y el número 8 que se trata de una consola desplegable para
observar el correcto funcionamiento del juego.
2.1.2 MonoDevelop
Al igual que Unity es multiplataforma, funciona sobre Windows, Linux y MacOS. Entre
sus características destacan la capacidad de realizar debug gráfico, autocompletado
de código, una interfaz sencilla y configurable, gestión de soluciones y la posibilidad de
incluir plugins para programar en otros lenguajes.
Las imágenes vectorizadas con las que trabaja este programa se componen de puntos
en un espacio virtual que se van uniendo por medio de trazados, para ser rellenados
posteriormente y así obtener imágenes de gran calidad que tienen coherencia a
cualquier tamaño.
16
Tiled es gratuito y multiplataforma y en él se puede configurar las dimensiones del
nivel (número de casillas y tamaño) y su diseño. Los niveles creados pueden ser
exportados en distintos formatos como: txm, csv o json.
En este proyecto se crearon varios ficheros con extensión csv y dimensiones 40x8
para simular distintos tableros empleados en el juego.
2.2 Tecnologías
2.2.1 C#
Hay que mencionar que en la industria de los videojuegos hay dos lenguajes que
despuntan sobre el resto, C# y C++. Se usa generalmente el primero cuando lo que se
busca es sencillez y el segundo para grandes juegos que requieren una buena gestión
de recursos como la memoria.
Photon proporciona una API que permite a los jugadores coincidir en una sesión de
juego compartida llamada “sala”, así como transferir mensajes e información en tiempo
real, entre los jugadores conectados. Una de las características de Photon es que
permite interactuar entre sí a los jugadores sin importar la plataforma desde la que
están conectados.
17
Para hacer uso del servicio se debe crear una cuenta en la página web de Photon y
crear una aplicación. Una vez creada esta aplicación, se debe descargar el asset de
Photon desde Unity e introducir el identificador de la aplicación creada para gestionar
la conexión al servidor.
En la figura 3 se puede observar la aplicación creada, la cual servirá como host para
todos aquellos usuarios que hagan uso del juego. Se puede observar que Photon
ofrece, también, información como el pico máximo de usuarios tanto en este mes
como en el anterior.
Aparte del número máximo de usuarios, Photon ofrece herramientas que permiten,
entre otras cosas, analizar el tráfico en el servidor. En el panel, que describe la figura
4, se pueden observar datos sobre el continente desde donde se conectan los
usuarios, el número máximo de usuarios concurrentes o el número máximo de salas
creadas, entre otras características.
18
Figura 4 – Analizador de rendimiento
2.2.3 XML
XML es un lenguaje de marcado similar a HTML desarrollado por el World Wide Web
Consortium (W3C). Proviene del lenguaje SGML y su primera versión data de 1998.
XML sirve para representar información estructurada de modo que pueda ser
almacenada, transmitida, procesada, visualizada e impresa por diversos tipos de
aplicaciones y dispositivos.
Las ventajas de XML frente a otros tipos de almacenamiento estructurado son que los
documentos son fácilmente procesables, se separa radicalmente el contenido y el
formato de presentación y está diseñado para cualquier lenguaje o alfabeto.
Se emplearon para el desarrollo del proyecto varias librerías que proporciona Unity
como parte de su asset store. Dichas librerías son las siguientes:
Text Mesh Pro, que permite darles a los juegos una interfaz más vistosa empleando
para ello fuentes y formatos de texto más avanzados que los que ofrece la interfaz por
defecto del programa. Es fácil de usar y hace uso de técnicas avanzadas de
representación de textos.
19
Tween, un pequeño paquete que incluye un único archivo de código. La gran ventaja
del paquete reside en que haciendo uso de él se permite que los objetos que
conforman el juego se muevan a través de la escena cambiando sus propiedades
(posición y rotación) de manera fluida.
Unity Test Runner era una librería antiguamente externa al propio programa, al igual
que las dos anteriores, aunque en las versiones más recientes de Unity se ha
incorporado plenamente. El objetivo de esta librería es ayudar al desarrollador a
probar el software realizado.
Unity Profiler, al igual que la librería anterior, está incluido en el propio programa y su
objetivo es la representación de la gestión de recursos (CPU y memoria entre otros) de
los que hace uso el juego durante su ejecución. Se uso esta librería para realizar las
pruebas de sistema.
2.3 Materiales
A la hora de implementar el juego se han recogido las reglas del juego de tablero y
además en la versión digital se han introducido algunas mejoras.
20
3. Metodología
Cada iteración funciona como un desarrollo de software independiente con sus fases
de análisis, diseño, implementación y pruebas. Las iteraciones no tienen por qué tener
la misma duración, ni una cantidad de tareas a realizar similar. Por ello tuvo que
planificarse previo a empezar el proyecto el número de iteraciones que se iban a
realizar, para el cumplimiento de los plazos, con su duración estimada, así como la
funcionalidad que se iba a implementar en cada iteración.
Las ventajas que ofrece este desarrollo con respecto a otros son que el coste de
introducir nuevos requisitos es reducido, es más fácil obtener impresiones sobre cómo
va el proyecto y ofrece gran flexibilidad ante posibles cambios.
Se valoró también la utilización de una metodología ágil, como Scrum, pero al final se
rechazó la idea debido a que suponía una dificultad mayor su seguimiento,
principalmente por tratarse un proyecto desarrollado por una sola persona.
21
3.2 Planificación
Siguiendo varios tutoriales (Arrioja, 2013, Gibson, 2014), y estudiando los elementos
del motor creé mi primer juego. Este juego es una copia sencilla del famoso
videojuego Flappy Bird, bautizado como Retarded Bird, cuya ejecución se puede
observar en la siguiente imagen.
22
Figura 6 – Retarded Bird
23
3.2.3 Etapa de integración
3.2.4.1 Iteración 1
Esta iteración se dedicó a realizar el prototipo básico del juego. Ese prototipo debía
tener un ajuste de la interfaz completa del juego, incluir la implementación de las
clases de negocio básicas como el game manager o el tablero, permitir cargar el
tablero desde un fichero csv y ejecutar correctamente la secuencia de partida para un
jugador moviendo su ficha a través del tablero según la puntuación del dado.
3.2.4.2 Iteración 2
3.2.4.3 Iteración 3
24
3.2.4.4 Iteración 4
3.2.4.5 Iteración 5
3.2.4.6 Iteración 6
En esta iteración se realizó la gestión del valor ganado (al llegar a un hito), su
comprobación y la actualización de valores, todo ello a través de un formulario.
También se introdujo otro formulario para calcular la nueva planificación (llamado
formulario de plan de proyecto) hasta el siguiente hito.
3.2.4.7 Iteración 7
3.2.4.8 Iteración 8
Iteración dedicada a comprobar la portabilidad del juego con versiones como la versión
escritorio de Windows, la versión móvil y tablet de Android y la versión WebGL, y
resolver posibles problemas de compatibilidad que el juego pudiera generar.
25
3.2.4.9 Iteración 9
3.2.4.10 Iteración 10
El objetivo en la décima y última iteración fue cambiar los formularios para resaltar la
importancia de los elementos que requieren de una entrada numérica por parte del
usuario, la creación de una clasificación online por puntos accesible para todos los
jugadores y aumentar la fluidez de las fichas para que el juego tenga un aspecto más
realista.
4. Análisis de requisitos
# DESCRIPCIÓN
RF01 El juego deberá ser jugado en modo multijugador.
RF04 El juego automatizará el cálculo de valores tales como el SPI, CPI o el coste total de
una fase a partir de unos parámetros introducidos por el jugador.
26
RF06 El juego contará con un dado como método para que el jugador avance las casillas
correspondientes.
RF07 El juego finalizará cuando un jugador gane, todos se queden sin dinero menos uno o
todos, menos uno, abandonen la partida.
RF09 Al finalizar la partida, el sistema mostrará un sumario con la posición de cada jugador
en la partida.
RF13 El jugador deberá introducir una nueva planificación para la siguiente fase al inicio y
al llegar a un hito.
RF14 El sistema permitirá tener acceso en todo momento a la información relevante del
proyecto como el plan de proyecto, el reporte de actuación, los empleados o el dinero
disponible.
RF15 Si se lanza el dado y sale un número entre 1 y 4 el sistema avanzará la ficha del
jugador normalmente, si sale un 5 o un 6 el sistema asignará un riesgo al jugador.
RF19 El sistema deberá, ante cualquier cambio en los atributos del jugador (número de
empleados, presupuesto…), actualizar la interfaz.
Se detallan en la tabla 3 los requisitos no funcionales del juego, es decir, los requisitos
que atañen a las características del funcionamiento y no a la funcionalidad en sí.
27
# TIPO DESCRIPCIÓN RELEVANCIA
RNF01 Portabilidad El juego deberá poder ejecutarse en Muy alta
versión escritorio en Microsoft Windows y
en móviles y tabletas Android.
5. Diseño e Implementación
Otras ventajas que presenta la arquitectura en tres capas con respecto a otros tipos de
arquitecturas son: reducir la carga en el lado del cliente, permitir una migración fácil de
una tecnología de persistencia a otra, facilidad para escalar el sistema o facilidad para
realizar actualizaciones futuras.
28
Figura 7 – Arquitectura en tres capas
· Capa de negocio: Capa donde reside la lógica del sistema, es decir, las funciones
que se ejecutan, el procesado de la información y la gestión de peticiones. En el
desarrollo esta capa coincide con la implementación del código realizado. En ella se
establecen, por tanto, todas las reglas que se deben cumplir. Esta capa se comunica
con la capa de presentación para recibir solicitudes y con la capa de datos o
persistencia para llevar a cabo la gestión de los datos. Esta capa de negocio se
comunica con dos servicios externos: uno, que gestiona la clasificación (dreamlo) y
otro que gestiona las partidas multijugador (Photon).
· Capa de datos: Capa encargada de la gestión de los datos del sistema. Puede estar
formada por varios sistemas gestores de bases de datos u otro tipo de
almacenamiento. Comunica con la capa de negocio y su función principal es
almacenar, leer y manipular datos. En este proyecto la capa de datos está
representada por los ficheros XML que almacenan los riesgos y los empleados, los
ficheros csv que almacenan los distintos tableros y la clasificación almacenada en el
servicio comentado.
29
5.2 Capa de presentación
A la hora definir la capa de presentación del juego se prestó atención a dos aspectos
principalmente. Por una parte, a la interfaz del usuario, y por otra a la gestión y
navegación por las diferentes escenas que implementan esta interfaz.
La interfaz de usuario del juego se puede dividir en dos. La interfaz jugable, es decir, la
interfaz con la que interactúa el jugador durante la partida. Y la interfaz navegable, es
decir, la interfaz por la que navega el jugador hasta que comienza una partida.
Aunque ambas partes formen un conjunto bien formado, el proceso seguido para la
realización de los dos componentes fue distinto.
La interfaz del juego tuvo como punto de partida e inspiración los elementos físicos del
propio tablero. Con esos elementos se intentó hacer una interfaz acorde que se
pareciera lo máximo posible al diseño original con algunas peculiaridades. La figura 8
muestra el tablero físico y la figura 9 muestra la interfaz resultante en la versión digital.
30
Figura 9 – Interfaz usuario del juego digital
La interfaz del juego en formato digital añade nuevos elementos dado que el tablero no
es el único activo indispensable para el desarrollo de la partida. En la imagen anterior
se puede observar, en la parte superior, información relevante para el jugador como
quién tiene el turno, la fase actual del desarrollo del proyecto en la que el jugador está
o el número de casillas por fase, dato importante para hacer el cálculo del plan de
proyecto para la fase.
Estos informes le sirven al usuario para tener disponible en todo momento información
relevante sobre su partida. En el informe que se puede observar en la figura 10 se
aprecia el reporte de actuación de la última fase recorrida (análisis de requisitos). En
este informe, por ejemplo, se muestran datos como el progreso planificado y real de la
fase, el coste planificado y real y los valores del EV, CPI y SPI. Por su parte, el otro
informe disponible, el informe del plan de proyecto, muestra los costes planificados
para la siguiente fase.
31
Figura 10 – Reporte de actuación
32
Cuando se llega a un hito el jugador deberá realizar también una reconfiguración total
de su equipo de trabajo (si así lo desea). La ventana de reconfiguración del equipo se
muestra en la figura 12 y en ella aparece una lista de todos los empleados disponibles
con una imagen (se ha decido asignarle una temática relacionada con monstruos), así
como su nombre, productividad y salario. El jugador deberá seleccionar los empleados
deseados y continuar.
Es importante hablar en este apartado sobre los colores elegidos para la interfaz. Para
ello se realizó una selección de posibles paletas de colores utilizando Adobe Color CC.
Después de descartar todas las anteriores se llegó a la paleta que le da color al juego.
Esta paleta se puede observar en la siguiente figura (figura 13).
33
La paleta de colores la comprenden cinco colores. Dos colores complementarios y
llamativos como el verde y el rosa que resaltarán los elementos más importantes del
juego. Dos colores monocromáticos de la misma gama como el blanco y el gris. Y un
color neutro como el beige.
De los cinco colores que tiene la paleta se pretendió que, a priori, todos tuvieran su
propio cometido, aunque hay algunas salvedades. Se utilizó el gris para los textos de
la interfaz, el rosa para resaltar los elementos relevantes (como los hitos o el turno del
jugador), el verde para elementos relacionados con la interfaz, el blanco ligeramente
azulado para los botones de los formularios, así como para las entradas y salidas de
texto y por último el beige como color de fondo del juego.
Estos iban a ser los colores principales inicialmente, pero es importante comentar que
se realizaron algunos cambios de última hora. Se hablará más adelante en esta
memoria (en el apartado de pruebas de aceptación) sobre ello, pero al acudir a una
empresa externa al proyecto para que dieran su valoración sobre el juego propusieron
algunos cambios, los cuales algunos fueron adoptados. Uno de ellos fue usar un
nuevo color, un azul “no demasiado agresivo”, como color para las diferentes ventanas
modales de reconfiguración. Inicialmente la ventana modal que encapsula al formulario
tenía color beige pero esto no era correcto dado que producía una ligera confusión con
el fondo.
34
Figura 15 – Mockup lobby
5.2.2 Escenas
Las escenas de Unity son elementos que contienen los entornos y menús del juego.
Cada escena se considera como un nivel único. El objetivo del programador es colocar
los distintos entornos, obstáculos y decoraciones en las escenas. La idea principal del
uso de escenas es construir el juego “a pedazos” para facilitar la simplicidad de los
distintos módulos.
35
· MENU_SCENE: Contiene el menú principal del juego. A través de esta escena se
puede acceder a la escena de lobby introduciendo un nombre de entre 1 y 16
caracteres y pulsando el botón jugar. También tiene otros dos botones: el botón de
puntuaciones para observar la clasificación global del juego y el botón salir para cerrar
el juego.
El código del proyecto se subdivide en varios módulos. Por una parte, se encuentra la
lógica del juego, por otra la lógica tanto del menú principal como del sumario que
aparece al terminar la partida, y por último todo el código relativo a la gestión del modo
multijugador. En la siguiente tabla (tabla 4) se observa la jerarquía de scripts del
sistema.
● Game
□ GameManager.cs
● BoardElements
● Empleados
□ ContenedorEmpleado.cs
□ Empleado.cs
● Jugador
□ Jugador.cs
● Riesgos
□ ContenedorRiesgo.cs
□ Riesgo.cs
□ RiesgoMover.cs
□ RiesgoProgreso.cs
□ RiesgoRestaDinero.cs
□ RiesgoSumaDinero.cs
□ RiesgoTurnoParada.cs
● Dado
□ Dado.cs
● Tablero
□ Tablero.cs
● Menu
□ MainMenu.cs
□ Sumario.cs
36
● Multiplayer
□ MainCanvasManager.cs
● CreateRoom
□ CreateRoom.cs
● Generic
□ DDOL.cs
● LobbyHandler
□ LobbyCanvas.cs
□ RoomLayoutGroup.cs
□ RoomListing.cs
● Networks
□ LobbyNetwork.cs
□ PlayerNetwork.cs
● RoomHandler
□ PlayerLayoutGroup.cs
□ PlayerListing.cs
□ RoomCanvas.cs
· Game: Esta carpeta contiene toda la lógica del juego. En ella se encuentra el script
correspondiente al game manager. Este script gestiona el tablero, gestiona el turno y
la lanzada del dado, muestra y actualiza los formularios, y crea los distintos objetos del
juego en tiempo de ejecución, como puede ser la información contenida en los
informes disponibles del jugador. También se encuentran, en esta carpeta, clases
básicas que gestionan los distintos elementos del juego como los riesgos y los
empleados, así como sus contenedores. Hay disponible una clase Dado cuya tarea es
obtener una puntuación al lanzar el dado y el renderizado de este elemento (con la
puntuación que toque) después de lanzarlo. En cuanto a la clase Jugador, en ella se
almacenan los datos de cada jugador y la gestión del movimiento de la ficha asignada.
Por último, se encuentra la clase Tablero cuyo objetivo es crear las distintas casillas en
la escena una vez leído el archivo csv que almacena los datos del tablero.
· Menu: Esta carpeta contiene dos clases. Por un lado, la clase MainMenu que
gestiona los botones del menú principal, se encarga de cargar la escena del lobby,
cerrar el juego si así se desea y mostrar las puntuaciones globales de los jugadores
que han jugado al juego. La segunda clase es el Sumario, cuya funcionalidad se basa
en la creación de las estadísticas al finalizar la partida, actualizar la tabla de
puntuaciones de acuerdo con la posición obtenida y finalizar la ejecución del juego
cuando el jugador así lo desee.
· Multiplayer: Contiene toda la lógica de la gestión online. Las clases anotadas como
“Canvas”, “LayoutGroup” o “Listing” tienen como objetivo dotar a la interfaz de distintas
funciones y crear los distintos objetos necesarios. Estos objetos son los botones con el
nombre de la sala y el nombre de los jugadores dentro de la sala. Cuando otro jugador
crea una sala, se crea un botón para todos los jugadores y al pulsarlo te introduce en
dicha sala. De esta carpeta hay que prestar especial atención a tres elementos que
son: la clase DDOL, la clase LobbyNetwork y la clase PlayerNetwork. Aunque las
funcionalidades de estos elementos ya se detallarán, al gozar de gran importancia, en
el apartado correspondiente al servidor Photon es importante mencionar que son las
clases que hacen posible, a grandes rasgos, la gestión multijugador.
37
5.3.2 Game Manager
El Game Manager es la clase más importante del juego al ser aquella que controla la
mayor parte de la lógica. Es por ello por lo que merece especial atención y una
explicación detallada de aquellos aspectos más importantes que en él se contienen.
La clase GameManager no es el único ejemplo que se podría poner para el uso del
patrón Singleton en este proyecto. En el siguiente fragmento de código (código 1) se
muestra el código relativo a la implementación de dicho patrón en la clase
mencionada.
Es importante desglosar en este apartado, a parte del uso del Singleton, información
relativa sobre los métodos más importantes implementados en la clase
GameManager. Algunos de estos métodos permiten gestionar las siguientes
funcionalidades:
38
valores numéricos a partir de unas entradas introducidas y permitir continuar si todos
los datos son correctos.
· Gestión del dado: Se trata de un método que permite la lanzada del dado. Este
método se puede observar en el siguiente código (código 2). En este método, primero
se comprueba si el jugador que pulsa el dado es el jugador que tiene el turno
actualmente. Si lo tiene se lanza el dado. En caso de que la puntuación sea un 5 o un
6 se ejecuta un riesgo para el jugador y se avanza. En caso de que sea 4 o menos, no
se ejecuta ningún riesgo. Después de llamar al método que permite el movimiento
(almacenado en la clase Jugador) se comprueba el valor devuelto. Si el valor devuelto
es un -1 se elimina al jugador al haberse quedado sin dinero y se desactiva la interfaz
(en caso de que solo quede un jugador en la partida se lanza el sumario dado que ese
será el ganador). Si el valor devuelto es un 0 se cambia el turno normalmente, si es un
1 se lanza el sumario de la partida porque el jugador ha llegado al final y si es un 2 se
muestran los formularios y la ventana de reconfiguración del equipo.
· Lanzar sumario: Se trata de un método que ordena en una lista a los jugadores en
función de las casillas recorridas para posteriormente cargar la escena del sumario de
la partida. El ganador aparecerá en primer lugar al haber recorrido más casillas. En
39
caso de empate en el número de casillas el jugador con más dinero aparecerá en una
mejor posición.
5.3.3 Tablero
En este apartado se va a hablar sobre los tableros, un elemento tan principal que sin él
no habría juego posible. Para ello se va a atender a distintos aspectos: la clase
Tablero, la estructura de los ficheros csv y la variabilidad de tableros que los jugadores
tienen disponibles.
La clase Tablero es la encargada de la gestión del tablero. Dentro del juego se adjunta
una instancia de esta clase a un objeto llamado tablero. Cuando se carga la escena
del juego, el script ejecuta su método de inicio (start) que permite la ejecución
secuencial de la función que inicializa el tablero como un array de 2 dimensiones de
tamaño 8x40 (tamaño que se consideró apropiado), la función para cargar el tablero a
través de un texto que recibe como parámetro (este tablero deberá tener las mismas
dimensiones que el array inicializado) y la función que “dibuja” el tablero, es decir, crea
un objeto en la escena por cada casilla del mismo.
Uno de los objetivos que se buscada con la creación de varios tableros es evitar que el
usuario se canse del juego con facilidad. Para favorecer la motivación para que el
usuario continúe usando el software se decidió crear tres tableros diferentes. En los
otros dos tableros desarrollados, en uno el presupuesto es de 25000$ y en el otro de
30000$. El número de casillas por fase también es variable, luego el estilo de juego
para un tablero u otro podrá variar notablemente. En la figura 17 se puede observar
uno de los otros dos tableros desarrollados a parte del descrito en el código anterior.
Este tablero tiene 46 casillas para la fase de análisis, 44 para la de diseño, 43 para la
implementación y 35 para las pruebas.
40
En el código que se presenta a continuación (código 4) se muestra la clase
LobbyNetwork. Los tres métodos que en ella se implementan tienen como objetivo
conectarse al servidor, unirse al lobby con el nombre de usuario escogido en el menú
principal y modificar la interfaz respectivamente.
Código 4 – LobbyNetwork.cs
Para la gestión del modo multijugador se creó una nueva clase llamada PlayerNetwork
que almacena las variables globales del juego como la lista de los jugadores dentro de
la partida, quién tiene el turno y opciones como el tablero o el número de empleados
iniciales. Esta clase contiene también unos métodos anotados como “PunRPC” que
permiten que todo el conjunto de los jugadores de la partida los ejecute cuándo se
produzca un evento que los desencadene. Estos métodos se usan para varias tareas.
Las más señaladas son cambiar el turno cuando el jugador que tiene actualmente el
turno lo ha acabado o para gestionar el turno si el jugador actual que lo tiene
abandona la partida. A continuación, se muestra el código (código 5) del cambio de
turno para todos los jugadores.
Cuando el jugador que tiene el turno lo finaliza realizará una llamada al método de
cambio de turno con el siguiente jugador como parámetro. Este método llama a un
41
método “PunRPC” que será ejecutado por todos los jugadores de la partida
(PhotonTargets.All) y que cambiará el turno al siguiente jugador y actualizará el
mensaje que informa al usuario de quién tiene el turno actualmente.
Para hacer persistente la instancia de esta clase se creó dentro de la escena del lobby
un objeto que tiene como componente el script llamado DDOL (acrónimo de
DontDestroyOnLoad) que evita que se borre al cambiar de escena. Dentro de este
objeto se encuentra adjunto (como objeto hijo) otro objeto que tiene como componente
el script PlayerNetwork. De esta manera sencilla se consigue que no se elimine la
clase que gestiona el modo online. A continuación, en el fragmento de código 6 se
muestra la sencilla implementación de la clase DDOL.
Código 6 – DDOL.cs
5.3.5 Sumario
Se crea este apartado para hablar sobre el sumario y mostrar su apariencia física dado
que es un elemento con importancia dentro del propio juego. En la figura 18 se puede
apreciar la escena del sumario. En ella se puede ver arriba a la derecha el logo del
juego que aparece en todas las escenas disponibles. En la parte central se muestra
una pequeña infografía de las estadísticas de los jugadores mostrando su posición
después de haber finalizado la partida, una imagen representativa (varias medallas; a
saber, de oro, plata, bronce y de color negro para el último) y su nombre. Y por último
aparece un botón que permite cerrar el juego.
42
Figura 18 – Sumario del juego
Dentro del código de la clase Sumario quería poner especial atención al código que
gestiona la actualización de la clasificación online. Dicho código puede ser observado
en el siguiente fragmento (código 7).
El método que añade una nueva puntuación llama al método de modificar puntuación
como una co-rutina pasándole como datos un nombre de usuario y una puntuación.
Esta puntuación será de 15 puntos para el primero, 10 para el segundo, 5 para el
tercero y ninguno para el cuarto (independientemente del número de jugadores que
haya en la partida).
43
El método de modificación busca en las puntuaciones almacenadas en la instancia de
la clase MainMenu (al abrir el juego se cargan estas puntuaciones del servicio
dreamlo) y comprueba si hay actualmente alguna puntuación del usuario pasado como
parámetro. Si lo hay se modifica el atributo del valor anterior a esa puntuación. Esto se
tiene que realizar de esta manera porque, a la hora de realizar la llamada a la API
REST que gestiona las puntuaciones, si ya hay un jugador con ese nombre se
sobrescribe la puntuación. Procediendo así se consigue que se sobrescriba la
puntuación que tenía antes con la suma de esta más la nueva puntuación
correspondiente a la partida recién jugada.
Los datos que se usan en el juego están almacenados en tres sitios diferentes. Por un
lado, están los datos de la interfaz definida en Unity. Estos datos se almacenan por el
motor en ficheros de configuración que se gestionan automáticamente a medida que
se van creando. Por otro lado, se encuentran los recursos que se usan dentro del
propio juego (empleados y riesgos) que están contenidos en ficheros XML, los tableros
contenidos en ficheros csv y por último se encuentra la clasificación online que se
gestiona a través de la página dreamlo y el servicio que ésta proporciona.
Los datos que almacena Unity no requieren de explicación, sin embargo, los otros tres
tipos de datos almacenados sí. Es por ello por lo que se especifican en los siguientes
puntos de manera más detallada.
Para almacenar los datos del juego se decidió emplear ficheros XML dado que se trata
de un método sencillo y una tecnología de la cual ya tenía conocimientos previamente
(Rusty, 2004). Los datos que se necesitaban almacenar eran los empleados y los
riesgos.
Para los empleados se creó una clase Empleado y otra ContenedorEmpleado que
contiene una lista de empleados y un método para cargar los empleados del XML. En
el código 8 se puede observar esta última clase mencionada.
44
Código 8 – ContenedorEmpleado.cs
45
Figura 19 – Diagrama UML de la herencia de Riesgo
46
5.4.3 Clasificación
A parte de las desventajas que tienen las tecnologías revisadas se encontró una
página web que permite la creación de una clasificación en la red. Una especie de API
REST que almacena la tabla de puntuaciones en un host llamado dreamlo y al que se
puede acceder a través de enlaces web.
47
disponibles el sistema. Este servicio permite un máximo de 1000 puntuaciones
ampliable si se contacta con el gestor del servicio. Para la problemática que me ocupa
se supusieron suficientes este número de entradas. A la derecha se encuentran los
diferentes enlaces que se deben ejecutar para realizar acciones sobre los datos de la
tabla. En cuanto a estos enlaces se usan principalmente dos: el primer enlace que
gestiona la creación/actualización de una puntuación y el último que devuelve todos
los valores de la tabla.
Por razones de seguridad, los enlaces de modificación no son visibles, la clave privada
de la clasificación tampoco ni, por supuesto, el enlace a la misma (que aparece arriba).
6. Evaluación y Pruebas
Este apartado tiene como objetivo comentar las pruebas realizadas en el juego
desarrollado. Las pruebas son un elemento fundamental en un desarrollo software y
deben realizarse siempre para evitar fallos no deseados.
Se ha decidido crear un sólo epígrafe para las pruebas tanto unitarias como de
integración dado que, por la naturaleza del propio programa, Unity, y de los juegos
como software desarrollado es casi imposible encontrar elementos aislados de código
que funcionen sin depender de otros.
48
no obtener bugs indeseados. De esta manera se subsanaron errores que aparecían al
producirse excepciones en el código.
Para llevar a cabo estas pruebas se ha hecho uso de una funcionalidad implementada
por Unity llamada Test Runner que permite su configuración y ejecución. El Unity Test
Runner hace uso de la librería NUnit que es una librería de pruebas de software libre
para lenguajes .Net.
El Test Runner permite ejecutar los test tanto en modo editor (edit mode) como en
modo de juego (play mode). Por la dificultad que tiene programar las pruebas en modo
de juego se optó por no hacer uso de esta funcionalidad sustituyéndola por, como he
mencionado anteriormente, ejecuciones del propio juego y comprobación de que todo
funcione como debe.
En cuanto a las pruebas de modo editor, si se ha hecho uso de ellas. Estas pruebas
consistían en la creación de una nueva clase que almacena las pruebas como propias
funciones al igual que ocurre con otras librerías de pruebas con JUnit en Java. A
continuación, se muestra el código (código 10) de una de las pruebas realizadas.
Como se puede observar, el Test Runner usa, como elementos para comprobar el
correcto funcionamiento de los métodos, aserciones que comprueban numerosas
condiciones como: que un número sea mayor, menor o igual que otro, o el contenido
de una cadena de texto, entre otras. En el método comprobado se puede ver como se
comprueba, primero que el nombre es nulo y después que, tras la ejecución del
método, el nombre no sea nulo.
49
6.2 Pruebas de sistema
Para realizar estas pruebas se procedió a crear una partida con dos jugadores. Uno
accedió al juego vía ordenador y el segundo desde su dispositivo móvil Android. Se
jugó la partida completa y se concluyó entonces que la partida podía ser jugada sin
ningún problema, puesto que no se produjo ningún error. Para el juego es indistinto
que una persona se conecte desde un dispositivo u otro.
50
Figura 21 – Unity Profiler
A parte de las gráficas que se generan también se puede observar en detalle cada uno
de los aspectos que se contemplan con información mucho más detallada. Para este
proyecto se habían establecido como requisitos no funcionales de rendimiento que el
juego no consumiera más de 2GB de memoria y que no bajase de los 24 fotogramas
por segundo que es el mínimo necesario para que el ojo humano tenga una sensación
de fluidez y velocidad.
En la figura anterior (figura 22) se puede observar con mayor detalle el uso de
memoria del sistema. En la primera línea aparece el total usado (245,7 MB) y el
desglose de esa cantidad por elementos. Observamos como Unity es el elemento que
más consume (135,1 MB), mono, que es la memoria usada por el código para guardar
variables, consume (18,8 MB), GfxDriver, la memoria que el controlador usa para
gestionar texturas y renderización, (96,9 MB) o el propio Profiler que al activar su
ejecución también consume recursos (13,7 MB).
51
Para comprobar que el juego superara los 24 fotogramas por segundo se observó, al
igual que en la imagen anterior la información detallada de la memoria, la información
en detalle del uso de la CPU. Esta información está representada en la figura 23. En
ella se puede observar que la tasa de refresco de la CPU es de 16,16 ms. Con esta
cantidad se aplicó la fórmula FPS = 1/T(s) con un resultado de aproximadamente 61
fotogramas por segundo. Luego se concluyó también que se cumplía el requisito no
funcional establecido.
A parte de esta tasa de refresco también se pueden observar otras tareas realizadas y
el uso en porcentaje y tiempo que hacen de la CPU. En la imagen, por ejemplo, se
puede ver que un 59% del uso de la CPU está dedicado a tareas de inicialización, o lo
que es lo mismo 9,54 ms, un 18.1% corresponde a overhead del editor en tiempo de
ejecución (o 3,01 ms) y un 5,6% (0,91 ms), por comentar otro aspecto interesante, a
tareas de renderizado de la cámara. El desglose es mucho más amplio pero el resto
de los procesos usan un porcentaje despreciable, al menos en este juego.
Una vez finalizado el juego se realizaron, también, las pruebas de aceptación. Para
realizar dichas pruebas se acudió a dos fuentes, a parte de la propia aceptación del
director del proyecto, Carlos. Por una parte, nos pusimos en contacto con la empresa
de desarrollo de videojuegos Concano Games, a los que le agradezco su ayuda
puesto que no tenían ninguna responsabilidad sobre el proyecto, con el objetivo de
que probaran el juego y dieran sus impresiones sobre la apariencia física del mismo.
Tras jugar un par de partidas comentaron el buen trabajo realizado y aprobaron los
elementos gráficos. Como es obvio, al tratarse de una empresa seria y profesional
propusieron algunas mejoras en el terreno gráfico que fueron tenidas en cuenta y otras
que a buen seguro serán estudiadas y evaluadas para proceder con su
implementación en el futuro.
Hay que mencionar que este juego será, en un futuro cercano, usado por los alumnos
del grado. Esto proporcionará nuevos reportes y añadirá una nueva dimensión a las
pruebas de aceptación. Una nueva dimensión que será tenida en cuenta para trabajos
próximos.
52
7. Conclusiones y trabajos futuros
7.1 Conclusiones
Al principio de este camino acepté un reto ambicioso por el mero hecho de probarme a
mí mismo que podía hacer algo que no estuviera estrictamente ligado al conjunto de
conocimientos adquiridos en la carrera. Espero que se me entienda, no es que no
haya realizado proyectos software antes, sino que ninguno de ellos había estado
enfocado en el campo de los videojuegos que tanto me apasiona.
Creo que mi trabajo y esfuerzo han valido la pena. Primero porque en este proceso,
que no siempre ha sido sencillo, me he encontrado con obstáculos que hábilmente he
solventado, de los cuales he aprendido mucho. Y segundo por haber creado un juego,
un proyecto, que estoy seguro no quedará “abandonado en el fondo un cajón”. Habrá,
digo convencido de ello, gente a los que servirá de ayuda.
Por supuesto la historia no queda aquí. Si bien es cierto que el juego está en una
versión cien por cien jugable, sería de necio frenar este espíritu imparable que crece
en mi interior. Hay aspectos variados que por falta de tiempo no han podido ser
implementados pero que en un futuro lo serán.
Al tratarse de un juego que se pretende que sea utilizado por cualquier persona que
quiera aprender sobre la gestión de proyectos, lo primero que quiero hacer es
implementar una traducción de este juego al inglés, al tratarse de la lengua de uso
más extendido por todo el mundo (obviando el chino y el español). De esta manera el
juego llegará a un público más amplio.
Otra de las cosas que nos hacía especial ilusión, tanto a Carlos como a mí era incluir
sonidos. Cualquier juego que se precie debe incluir sonidos. Los sonidos hacen de la
experiencia de juego más rica y por tanto aumenta el interés por parte del usuario final.
Una música calmada o un sonido esporádico pueden hacer que un juego bueno, como
es éste, se convierta en algo fabuloso. En caso de que no guste el componente
audible, el usuario siempre podrá silenciar el volumen.
53
En cuanto al aspecto gráfico se desea mejorar teniendo en cuanta la retroalimentación
obtenida. En este sentido no sólo se plantea un cambio de colores sino la inclusión de
pieles que aporten distintas temáticas al juego. Esto permitirá acercar el juego a
distintos públicos, por ejemplo, a niños a través de una temática infantil o a
profesionales de distintos ámbitos con temáticas relacionadas con su profesión.
Como última mejora, había pensado en incluir una base de datos en la nube que
gestione el registro de los usuarios. Si bien es cierto que el mundo de desarrollo de
videojuegos me llama especialmente la atención, lo que más me gusta de la
informática es todo lo relacionado con la gestión de datos y veo en este proyecto una
clara oportunidad para abrirme a nuevos horizontes que no voy a desaprovechar.
8. Referencias
- Arlow, J. & Neustadt, I. (2005). UML 2 and the Unified Process: Practical Object-Oriented
Analysis and Design. Addison-Wesley.
- Photon Engine. (2018). Class List. Recuperado en febrero de 2019, de Photon Engine
Networking: https://doc-api.photonengine.com/en/pun/current/annotated.html
- Photon Engine. (2018). Public API. Recuperado en febrero de 2019, de Photon Engine
Networking: https://doc-api.photonengine.com/en/pun/current/group__public_api.html
- Unity Technologies. (2018). Game Objects. Recuperado en febrero de 2019, de Unity Manual:
https://docs.unity3d.com/Manual/GameObjects.html
54
- Unity Technologies. (2018). Sprites. Recuperado en febrero de 2019, de Unity Manual:
https://docs.unity3d.com/Manual/Sprites.html
- Unity Technologies. (2018). Test Runner. Recuperado en febrero de 2019, de Unity Manual:
https://docs.unity3d.com/Manual/testing-editortestsrunner.html
55