Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
Justificación y objetivos
El trabajo consiste en el desarrollo de un videojuego para navegador web. Para su realización se
tratará de replicar un videojuego ya existente, y al que se puede jugar actualmente en cualquier
navegador que soporte la tecnología Flash. De esta manera se podrá centrar en el desarrollo del
videojuego y el estudio de las tecnologías necesarias. A diferencia del videojuego que se pretende
imitar, este se desarrollará haciendo uso de tecnologías web actuales, así se demostrará cómo, hoy
en día, se puede prescindir de Flash para el desarrollo de aplicaciones web.
Hace un año intenté trabajar en una propuesta de trabajo de fin de grado, pero no conseguía mo-
tivarme, lo que me llevó a terminar dejándolo de lado y decidí empezar un año nuevo con otra
propuesta distinta. Esta vez tenía claro que quería hacer un videojuego. Desde niño siempre me
han gustado los videojuegos y durante la carrera me he ido dando cuenta lo mucho que me gusta
diseñarlos y programarlos.
Decidí que el juego usaría la plataforma web por dos motivos. El primero es la facilidad y la
accesibilidad que tienen, no requieren de instalación previa y todo ordenador predispone de un
navegador web. El otro motivo es aprovechar para aprender a usar tecnologías que no he utilizado
durante la titulación y que pueden ser de utilidad en el futuro.
En resumen, los objetivos que se persiguen son los siguientes:
Aplicar los conocimientos aprendidos a lo largo de la carrera y, fortalecerlos y ampliarlos
con un aprendizaje autodidacta.
Estudiar y utilizar algunas de las tecnologías web actuales, que se usan a día de hoy en el
mundo profesional y, con ello, probar que la tecnología Flash está desfasada.
Desarrollar un videojuego para navegador web, y que soporte la conexión simultánea de
varios usuarios.
3
Agradecimientos
A todos los profesores del grado de ingeniería multimedia,
por todo lo que he aprendido de ellos.
A mis amigos y compañeros de clase,
por hacer de mi tiempo en la universidad algo especial.
4
Dedicatoria
Dedicado a toda mi familia,
especialmente a mi padre y a mi madre.
5
Citas
"Bienaventurados los pobres de espíritu, porque de ellos es el Reino de los Cielos"
Jesús de Nazaret
6
Índice de contenidos
1. Introducción 12
2. Marco teórico 13
2.1. Qué es Flash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2. Historia de Flash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.2.1. FutureWave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.2.2. Macromedia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.2.3. Adobe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.2.4. El fin de Flash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.3. Qué es un videojuego web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.3.1. Tecnología . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.3.2. Realm of the Mad God . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.3.3. Sports Heads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.3.4. Alien Hominid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.3.5. Happy Wheels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.3.6. Bloons TD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.3.7. World’s Hardest Game . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.3.8. Agar io . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.3.9. Onslaught Arena . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.4. Tecnologías para desarrollo de videojuegos web . . . . . . . . . . . . . . . . . . 27
2.4.1. Canvas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.4.2. Babylon.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.4.3. Phaser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.4.4. PlayCanvas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3. Objetivos 30
4. Metodología 31
4.1. Gestión del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.2. Herramientas utilizadas para el desarrollo . . . . . . . . . . . . . . . . . . . . . 31
4.2.1. Visual Studio Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.2.2. Google Chrome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.2.3. Blender . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
8
4.2.4. Tiled . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.2.5. Piskel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.2.6. GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
5. Cuerpo del trabajo 35
5.1. Diseño del juego . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
5.2. Planificación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
5.3. Iteración 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
5.3.1. Preparativos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
5.3.2. Bucle del juego . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
5.3.3. Conexión y control del jugador . . . . . . . . . . . . . . . . . . . . . . . 45
5.4. Iteración 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.4.1. Babylon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
5.4.2. Motor de físicas p2js . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5.4.3. Cargado del mundo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
5.5. Iteración 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.5.1. Inteligencia Artificial . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.5.2. Nidos de enemigos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
5.5.3. Diseño de las armas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
5.5.4. Event Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.6. Iteración 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
5.6.1. De Blender a Babylon . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
5.6.2. Assets Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
5.6.3. Interfaz gráfica de usuario . . . . . . . . . . . . . . . . . . . . . . . . . 66
5.7. Iteración 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
5.7.1. Sistema de sonido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
5.7.2. MongoDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
6. Conclusiones 70
7. Bibliografía 71
8. Glosario 73
9
Índice de figuras
1. Logotipo de Flash . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2. Versión de prueba de Future Splash . . . . . . . . . . . . . . . . . . . . . . . . . 14
3. Logotipo de Macromedia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4. Logotipo de Adobe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
5. Logotipo de newgrounds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
6. Realm of the Mad God . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
7. Interfaz de Realm of the Mad God . . . . . . . . . . . . . . . . . . . . . . . . . 20
8. Sports Heads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
9. Alien Hominid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
10. Happy Wheels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
11. Bloons TD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
12. World’s Hardest Game . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
13. Agar io . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
14. Onslaught Arena . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
15. Logotipo de BabylonJS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
16. Logotipo de Phaser.io . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
17. Logotipo de PlayCanvas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
18. Logotipo de VS Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
19. Logotipo de Chrome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
20. Logotipo de Blender . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
21. Logotipo de Tiled . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
22. Logotipo de Piskel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
23. Logotipo de GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
24. Logotipo de Node . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
25. Estructura de la aplicación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
26. Prototipo del juego con dos jugadores (triángulos azules) y múltiples disparos
(triángulos rojos) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
27. Escena básica de Babylon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
28. Ejemplo de uso de Tiled para crear la matriz de colisiones . . . . . . . . . . . . . 55
29. Estado del juego al final de la segunda iteración . . . . . . . . . . . . . . . . . . 57
30. Armas en Babylon Heroes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
31. Instalación del convertidor de Blender a Babylon . . . . . . . . . . . . . . . . . 63
10
32. Modelo 3D del jugador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
33. Resultado de la exportación del modelo 3D . . . . . . . . . . . . . . . . . . . . 64
34. Barras de vida y magia del jugador . . . . . . . . . . . . . . . . . . . . . . . . . 66
35. Estado del juego al final de la cuarta iteración . . . . . . . . . . . . . . . . . . . 67
36. Logotipo de MongoDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
11
1. Introducción
En el pasado se recurría mucho a la tecnología Flash (Shockwave Flash) para todo tipo de aplica-
ciones web, reproducción de vídeos, juegos en línea, etc. Con la llegada de HTML5 y las constan-
tes mejoras de JavaScript, Flash ha quedado desfasada, sin embargo algunos sitios web y aplica-
ciones siguen utilizándola.
Un ejemplo es el videojuego Realm of the Mad God, en el cual varios jugadores combaten en
equipo derrotando enemigos, adquiriendo niveles de experiencia, y mejorando su equipamiento,
para poder acabar con enemigos aún más poderosos, hasta llegar al jefe final The Mad God.
En este trabajo se verán los diversos usos que se le ha dado a la tecnología Flash y cómo han
ido evolucionando el resto de tecnologías web, que a día de hoy nos permiten prescindir de flash;
además de la aplicación de estas nuevas tecnologías con el fin de desarrollar un videojuego en
línea.
12
2. Marco teórico
En este apartado se hará un recorrido de la historia de Flash, la importancia que ha tenido para las
aplicaciones web, y por qué ha llegado a su fin. También se analizarán distintos videojuegos de la
plataforma web, algunos que hacen uso de flash y otros que no, para conocer sus posibilidades, y
tener una idea de lo que se pretende con este trabajo.
Además, se estudiarán algunas de las tecnologías web con las que, en la actualidad, se puede
desarrollar un videojuego web.
2.1. Qué es Flash
Cuando hablamos de Flash, normalmente nos referimos a Flash Player, que se clasifica como
reproductor multimedia. Sin embargo, en ocasiones se utiliza para referirse al entorno de desarrollo
o a los archivos generados.
Figura 1: Logotipo de Flash
Fuente: wikipedia.org
Durante su ciclo de vida, Flash se ha usado sobre todo para la reproducción de cortos o anima-
ciones con imágenes en dos dimensiones. Aunque también se ha recurrido mucho a Flash para el
desarrollo de videojuegos web.
Dicho esto, Flash Player es un plug-in, un complemento que permite al navegador web reprodu-
cir los ficheros de extensión .swf (Shockwave Flash), que requiere estar instalado en el propio
navegador.
13
2.2. Historia de Flash
2.2.1. FutureWave
Antes de Flash existía el producto SmarthSketch, publicado por FutureWave Software. Este era
una aplicación de dibujado vectorial para el sistema operativo PenPoint. Mas tarde se portó a
Windows y Mac.
Con el auge de internet, FutureWave se dió cuenta de su potencial y, en 1995, añadieron la funcio-
nalidad de animación por fotogramas, y lanzaron la nueva aplicación con el nombre de FutureS-
plash Animator, para PC y Macintosh.
Figura 2: Versión de prueba de Future Splash
Fuente: taringa.net
FutureWave intentó vender su producto a Adobe, pero la oferta fue rechazada en ese momento.
Empresas como Microsoft, Disney, o la cadena de televisión Fox hicieron uso de FutureSplash
para sus páginas web.
14
2.2.2. Macromedia
En noviembre de 1996, FutureSplash fue adquirida por Macromedia, y este renombró y relanzó
FutureSplash Animator como Macromedia Flash 1.0. Este consistía en dos sistemas, un editor y
animador de gráficos conocido como Macromedia Flash, y un reproductor conocido como Ma-
cromedia Flash Player.
Figura 3: Logotipo de Macromedia
Fuente: wikipedia.org
Macromedia distribuyó Flash Player como un plugin gratuito para navegadores, con la intención
de extenderse en el mercado rápidamente. En 2005, la mayoría de ordenadores de todo el mundo
tenían instalado Flash Player sobre los otros reproductores web, incluyendo Java, QuickTime,
RealNetworks y Windows Media Player.
Macromedia mejoró entre 1996 y 1999 añadiendo MovieClips, Actions (el precursor de ActionS-
cript), y la composición alfa, entre otras características. Conforme Flash maduraba, Macromedia
cambió el objetivo de su aplicación como una herramienta de gráficos hacia una herramienta para
la plataforma web.
En 2000, la primera gran versión de ActionScript fue desarrollada, y lanzada con Flash 5. Este
soportaba programación orientada a objetos, unos componentes para la interfaz de usuario mejora-
dos, y otras funcionalidades de programación. La última version de Flash lanzada por Macromedia
fue Flash 8, la cual se centraba en mejoras gráficas como filtros, difuminado, sombras, etcétera.
15
2.2.3. Adobe
Macromedia fue adquirida por Adobe el 3 de diciembre de 2005, y con ella toda su línea de
productos, incluyendo Flash, Dreamweaver, Director/Shockwave, Fireworks y Authorware. Todos
ahora en manos de Adobe.
Figura 4: Logotipo de Adobe
Fuente: wikipedia.org
En 2007, la primera versión de Flash por Adobe fue Adobe Flash CS3 Professional, la novena gran
versión de Flash. Introducía el lenguaje de programación ActionScript 3.0, el cual soportaba prac-
ticas de programación modernas y permitía que las aplicaciones de negocios fuesen desarrolladas
con Flash.
En 2008, se lanzó la décima versión, Adobe Flash CS4. Flash 10 mejoraba las capacidades de
animación dentro del editor, añadiendo un panel para edición del movimiento, animación de obje-
tos 3D básicos, animación basada en objetos, y otras funcionalidades de texto y gráficos. Incluía
también un motor 3D que permitía transformaciones de los objetos en el espacio 3D (posición,
rotación y escalado).
También en 2008, Adobe lanzó la primera versión de Adobe Integrated Runtime (que se conocería
como Adobe AIR), un motor que sustituyó a Flash Player, y que aportó capacidades adicionales
al lenguaje ActionScript 3.0.
En 2014, Adobe AIR alcanzó la cifra de 1 billón de instalaciones en todo el mundo. Adobe AIR fue
votada para el Mejor producto de Desarrollo de Aplicaciones Móvil en el Consumer Electronics
Show (Feria de Electrónica de Consumo) durante dos años consecutivos (CES 2014 y CES 2015).
En 2016, Adobe renombró Flash Professional, la principal herramienta de contenido Flash, a Ado-
be Animate. Con la intención de que los desarrolladores empezaran a favorecer HTML5 en lugar
de Flash, y desarrollar para los nuevos estándares de la web.
16
2.2.4. El fin de Flash
A pesar de que Flash llegase a ser una plataforma dominante para contenido multimedia online,
está siendo lentamente abandonado ya que Adobe favorece la transición a HTML5, debido entre
otras cosas a sus fallas de seguridad y los recursos necesarios para su mantenimiento.
Apple restringió el uso de Flash para iOS en 2010 debido a que no funcionaba correctamente
en sus dispositivos móviles, tenía un impacto negativo en la vida de la batería, y era innecesario
para el contenido online. Como resultado, no fue adoptado por los dispositivos de Apple, lo que
redujo la base de usuarios y animó a adaptarse a las funcionalidades de HTML5, como canvas y
los elementos de vídeo, que sustituyen Flash sin la necesidad de plugins.
En julio de 2017, Adobe anunció que declararía el fin de Flash para finales del año 2020, y que
cesará el soporte, la distribución y las actualizaciones de seguridad de Flash Player.
La plataforma Flash continuará en la forma de Adobe AIR, que continuará con su desarrollo, y
OpenFL, una implementación de código abierto de Flash. Adicionalmente, Adobe Animate coni-
nuará siendo desarrollada aún después de 2020.
Desde las versiones de los navegadores Chrome 76 y Firefox 69, Flash está desactivado por defec-
to. Los usuarios que quieran reproducir contenido Flash necesitan activar manualmente el plugin
durante cada sesión y para cada sitio web. Además, los navegadores muestran advertencias sobre
la eliminación completa de Flash para después de diciembre de 2020.
2.3. Qué es un videojuego web
Un videojuego web o videojuego de navegador es todo aquel que se juega mediante un nave-
gador web (Internet Explorer, Mozilla Firefox, Opera, Google Chrome, Safari etc). Este tipo de
videojuegos acostumbran a complementar el código HTML con Flash, JavaScript y PHP. Ejem-
plos famosos de videojuegos de navegador son Sherwood Dungeon, Ogame, ZeroG Commander,
Medievol, Ikariam o Travian.
Estos videojuegos han crecido a la par que lo hacía la web. El usuario normalmente no necesita
17
realizar instalaciones extra para jugar. Estos archivos se ejecutan en el navegador, sin la necesidad
de ejecutar otros programas, pero si se pueden necesitar plugins.
La principal diferencia con los videojuegos de videoconsola o de computadora es que los de nave-
gador son normalmente independientes de la plataforma, basados exclusivamente en tecnologías
usadas por el cliente (plugins o players). Habitualmente, todo lo que se requiere para jugar a un
videojuego de navegador es un navegador web y el plugin apropiado.
2.3.1. Tecnología
Dentro de la tecnología de los videojuegos de navegador, existen tipos diferentes de plugins, la
mayoría gratuitos, como la máquina virtual de Java, Adobe Flash Player entre otros. Además
existen videojuegos donde no se necesitan plugins externos y hacen uso del lenguaje JavaScript
para darle usabilidad al videojuego. Videojuegos como Ogame o Ikariam hacen uso de JavaScript
de diferentes formas.
Los videojuegos que requieren plugins son procesados normalmente en el ordenador del usuario,
en vez de ser en el servidor que los almacena. No obstante existen videojuegos con capacidad
multijugador que requieren de ambos procesos: una aplicación gráfica ejecutada en el ordenador
del usuario que se comunica con un servidor que gestiona las partidas.
Los videojuegos más populares de la actualidad son los videojuegos de estrategia en tiempo real
jugados vía navegador gracias al desarrollo de nuevas tecnologías como Flash y Java.
En definitiva, los videojuegos Flash pueden considerarse un tipo de videojuegos de navegador.
Los hay de muy diversos géneros, como acción, estrategia, aventuras, plataformas, simulación,
deportes, carreras, etc. Existen sitios web gratuitos enteramente dedicados a este tipo de videojue-
gos, como minijuegos.com , agame.com o newgrounds.com. Los videojuegos Flash más avanzados
pueden incluir gráficos 3D, pero en general se limitan a las dos dimensiones. También es común
que incluyan una opción para establecer la calidad de los gráficos (baja, media, alta), lo cual re-
sulta especialmente útil para gente que posee ordenadores con insuficiente rendimiento de vídeo o
conexiones de baja velocidad.
18
Figura 5: Logotipo de newgrounds
Fuente: newgrounds.com
2.3.2. Realm of the Mad God
Figura 6: Realm of the Mad God
Fuente: store.steampowered.com
Juego que junta los géneros de mmo (multijugador masivo online) y bullet hell, en cooperativo. Los
jugadores controlan personajes transportados al reino de Oryx. Los jugadores sirven de alimento
para los esbirros y abominaciones que habitan, y su misión es extinguirlos. La muerte del personaje
19
es permanente, el personaje del jugador se pierde con todo su equipamiento, aunque hay métodos
para transferir algunas de las pertenencias al siguiente personaje del jugador. Hay diferentes clases
de personaje para aumentar la variedad y enfatizar el juego en equipo.
Figura 7: Interfaz de Realm of the Mad God
Fuente: wikipedia.org
Como la mayoría de juegos web, es gratuito, sin embargo tiene microtransacciones (o micropagos)
opcionales, para aumentar las posibilidades del jugador y hacerlo más poderoso. Cabe decir que,
como muchos juegos con micropagos, el juego llega a un punto en que pagar hace tan fácil el
videojuego que es injusto para los jugadores que no pagan, empeorando la experiencia de estos.
20
2.3.3. Sports Heads
Figura 8: Sports Heads
Fuente: minijuegos.com
Sport Heads o coloquialmente conocido como çabezones", es un juego multijugador local de uno
contra uno. Cada jugador controla a un futbolista cabezón, que puede saltar y chutar. Los partidos
duran dos minutos, y pueden aparecer objetos que potencian o perjudican al jugador: congela-
ción, bombas, cambio de tamaño o velocidad, entre otros. Este juego es muy popular entre los
estudiantes universitarios para matar el tiempo.
Sport Heads es en realidad una saga de juegos con una gran variedad de deportes, pero el de fútbol,
con la liga inglesa en concreto, es el más popular sin duda.
21
2.3.4. Alien Hominid
Figura 9: Alien Hominid
Fuente: youtube
Alien Hominid comenzó como un juego Flash programado por Tom Fulp y animado por Dan
Paladin, el cual fue lanzado en la página Newgrounds.com en 2002. A menudo se le refiere como
Alien Hominid "prototype"por sus creadores. El juego consistía en un nivel con dos jefes. Se
volvió muy popular entre la comunidad de jugadores de la web. A pesar de sus bastante básicas
mecánicas: moverse, saltar y disparar, el juego explotaba perfectamente el potencial de Flash con
un estílo artístico muy vistoso.
Ese mismo año, se les acercó John Baez como fan de Alien Hominid y les propuso hacer una
versión del juego para consolas, y ofreciéndose a producir el juego. Paladin y Fulp vieron bien la
idea y juntos fundaron The Behemoth.
En sólo dos años, Alien Hominid se convirtió en un proyecto mucho mas grande que su prototipo.
The Behemoth decidió aferrarse al estilo 2D del original, aún teniendo la posibilidad de usar el 3D.
El juego se rehizo completamente para ser lanzado en consolas y se le añadieron más mecánicas,
música, niveles, etc.
22
2.3.5. Happy Wheels
Figura 10: Happy Wheels
Fuente: happywheels.game
Happy Wheels es un juego basado en la física ragdoll desarrollado y publicado por Fancy Force.
Creado por el diseñador de videojuegos Jim Bonacci en 2010, el juego cuenta con varios persona-
jes, que utilizan vehículos diferentes, a veces anormales, para atravesar muchos niveles del juego.
El juego es conocido por su violencia gráfica y sus mapas, que son generados por los usuarios.
La física ragdoll (muñeco de trapo en inglés) es un procedimiento de animación para simular el
movimiento de un cuerpo muerto. El sistema interpreta las características del cuerpo como una
serie de huesos rígidos conectados entre sí, usando bisagras como articulaciones. La simulación
modela lo que ocurre con el cuerpo cuando se cae al suelo, como si de un muñeco se tratase.
23
2.3.6. Bloons TD
Figura 11: Bloons TD
Fuente: ninjakiwi.com
Bloons Tower Defense (también conocido como Bloons TD) es un juego que pertenece a la serie
Bloons, creado y producido por Ninja Kiwi. Desarrollado como juego de navegador, usando la
plataforma Adobe Flash, fue lanzado en 2007.
En el juego los jugadores tratan de impedir que globos lleguen al final de un camino que recorren.
Para ello el jugador puede construir torretas (monos en este caso) que atacarán a los globos a su
alcance, hay de muchos tipos y diferentes características.
24
2.3.7. World’s Hardest Game
Figura 12: World’s Hardest Game
Fuente: youtube
Un sencillo juego donde el jugador controla una caja y debe alcanzar el final del nivel sin ser
tocado por otros objetos del juego. Consistía de 20 niveles, y como su propio nombre indica el
juego es bastante difícil, lo que aumentó su popularidad.
2.3.8. Agar io
Agar.io es un videojuego de navegador multijugador masivo online, publicado en 2015. La pers-
pectiva del juego es top-down, es decir, un ángulo de cámara que muestra al jugador y el área
circundante desde arriba. Este juego se hizo bastante famoso en muy poco tiempo a pesar de su
simpleza.
25
Figura 13: Agar io
Fuente: agar.io
El jugador empieza con una célula pequeña y tiene como objetivo ser lo más grande que pueda.
Para lograr este objetivo el jugador debe mover su célula por el mapa para comer los pequeños
puntos de colores que aumentan su masa además de tragar otras células al colocarse directamente
sobre ellas y evitar ser presa de células más grandes.
2.3.9. Onslaught Arena
Figura 14: Onslaught Arena
Fuente: experiments.withgoogle.com
26
Un sencillo juego hecho con canvas y JavaScript. El jugador se encuentra en una arena cerrada
en la que van apareciendo oleadas de enemigos. El objetivo es sobrevivir lo máximo posible para
alcanzar mayor puntuación. Los enemigos sueltan distintos tipos de armas al morir.
2.4. Tecnologías para desarrollo de videojuegos web
En la actualidad existen muchas herramientas que permiten el desarrollo de videojuegos web sin
hacer uso de Flash. Por lo general, la mayoría recurre al elemento de HTML5 canvas.
2.4.1. Canvas
Canvas (lienzo traducido al español) es un elemento HTML incorporado en HTML5 que permite
la generación de gráficos dinámicamente. Básicamente permite dibujar elementos en dos dimen-
siones.
Consiste en una región dibujable definida en el código HTML con atributos de altura y anchura.
Con código JavaScript se puede acceder a la zona, lo que permite la modificación de lo que se
dibuja en tiempo real. El elemento es soportado en las versiones actuales de los navegadores
Mozilla Firefox, Google Chrome, Internet Explorer, Safari, Konqueror y Opera.
2.4.2. Babylon.js
Figura 15: Logotipo de BabylonJS
Fuente: babylonjs.com
27
Babylon es un motor gráfico 3D para canvas. Dispone de todas las funcionalidades básicas de un
entorno 3D: mallas, transformaciones, texturas, materiales, cámaras, luces y sombras, animacio-
nes, efectos de partículas, etc. Además de otras funcionalidades orientadas a videojuegos, como
sistema de físicas, interfaces de usuario o reproducción de sonido.
Uno de los atractivos de Babylon es que cuenta con Playground, una herramienta online que per-
mite hacer el código en el entorno y ver el resultado inmediatamente, sin necesidad de almacenar
ficheros de manera local.
Por otra parte Babylon también ha sido usado para educación en medicina, entrenamiento militar
o modelado de lugares históricos.
2.4.3. Phaser
Figura 16: Logotipo de Phaser.io
Fuente: phaser.io
Phaser es un motor de videojuegos 2D con el que se puede desarrollar tanto juegos de escritorio
como para web o móviles. Aporta a canvas una visualización sencilla de las imágenes y animacio-
nes, reproducción de audio y motor de físicas.
28
2.4.4. PlayCanvas
Figura 17: Logotipo de PlayCanvas
Fuente: playcanvas.com
PlayCanvas es un motor de juego 3D que además consta de una plataforma para la edición y
creación de elementos 3D simultánea desde distintos ordenadores, a través de una interfaz en
el navegador. El motor es capaz de la simulación de físicas de cuerpos rígidos, audio en tres
dimensiones, y animaciones 3D.
Cuenta con el apoyo de compañías como Activision y Mozilla. Otras compañías usan PlayCanvas
en sus proyectos de diferentes disciplinas de contenido interactivo 3D en la web.
Hoy en día, este tipo de tecnologías son indispensables para el desarrollo de un videojuego web,
ya que son las encargadas del dibujado de la imagen, ya sea 3D o 2D. Sin embargo, pueden ser
complementadas con distintas tecnologías externas para aumentar sus capacidades. Por ejemplo,
añadir una base de datos para hacer una tabla de puntuaciones o, crear un servidor que comunique
a los jugadores para un videojuego multijugador.
29
3. Objetivos
El objetivo principal de este trabajo es desarrollar un videojuego del género multijugador masivo
en línea (mmo) para navegador web.
Para ello se analizarán las características y mecánicas que el videojuego debe cumplir y se
estudiaran las técnicas y herramientas que lo hagan posible. En el trabajo se reflejarán los
conocimientos adquiridos en la carrera, como el uso del lenguaje de programación JavaScript,
entre otras herramientas de desarrollo web. Además se profundizará en el aprendizaje de estos
campos y de herramientas nuevas como los motores gráficos. Con esto se persigue ampliar los
conocimientos aprendidos a lo largo de la titulación y aprender a usar tecnologías a las que se
recurre en el mundo profesional.
También cabe mencionar que al haberse escogido un motor gráfico en tres dimensiones para la
realización del videojuego, el modelado de los elementos 3D no formará parte de los objetivos
del trabajo, ya que supone un coste muy alto para el desarrollo, a diferencia de los elementos 2D.
Dicho esto, los elementos 3D usados para el videojuego serán obtenidos de sitios web gratuitos
como free3d.com, sketchfab.com o turbosquid.com.
Objetivos específicos
Implementación de un sistema cliente/servidor para la conexión entre usuarios.
Desarrollo de las mecánicas del videojuego.
Implementación de un sistema de físicas 2D.
Implementación de un motor gráfico 3D.
Diseño de los elementos gráficos 2D.
Implementación de una base de datos para la tabla de puntuaciones.
30
4. Metodología
Para el desarrollo del videojuego se ha seguido una metodología de desarrollo ágil. El objetivo
de este tipo de metodologías es minimizar los riesgos o excesos en el presupuesto, dividiendo
el proyecto en tareas cortas. En las metodologías de desarrollo ágiles, las tareas se reparten en
grupos de etapas repetitivas, conocidas como iteraciones. Estas suelen tener una duración de 1 o 2
semanas, pero existen metodologías ágiles con iteraciones de hasta 4 semanas.
Las fases de desarrollo de cada tarea se dividen en pendiente, cuando es recién creada o no se ha
empezado a trabajar en ella; en desarrollo, cuando está siendo desarrollada; y finalizada, cuando
la tarea ha sido terminada y se procede a iniciar el desarrollo de una nueva tarea.
4.1. Gestión del proyecto
Aunque no sea el método más profesional, la gestión de las tareas del trabajo se ha llevado con
apuntes en un cuadernillo. El ser un proyecto de una sola persona lo hace cómodo y rápido. Nor-
malmente, equipos de desarrollo profesionales usarían herramientas de escritorio u online para
gestionar las tareas.
4.2. Herramientas utilizadas para el desarrollo
4.2.1. Visual Studio Code
Figura 18: Logotipo de VS Code
Fuente: wikipedia.org
31
Entorno de desarrollo integrado (IDE) utilizado para la creación del código fuente. Es gratuito y,
aunque sirve como un simple editor de texto, está especialmente enfocado para el desarrollo web.
4.2.2. Google Chrome
Figura 19: Logotipo de Chrome
Fuente: wikipedia.org
Navegador web utilizado para el visualizado del juego. Entre todos los navegadores web, este
destaca por sus herramientas para desarrollador.
4.2.3. Blender
Figura 20: Logotipo de Blender
Fuente: blender.org
Programa de modelado 3D. Se ha utilizado para convertir los modelos descargados al formato
apropiado para el motor gráfico.
32
4.2.4. Tiled
Figura 21: Logotipo de Tiled
Fuente: mapeditor.org
Editor de mapas 2D por cuadrícula. se ha utilizado para el diseño del suelo del mundo 3D (el cual
es plano), y para posicionar los bloques de colisiones (arboles, rocas, muros).
4.2.5. Piskel
Figura 22: Logotipo de Piskel
Fuente: piskelapp.com
Herramienta online de dibujado en pixel art. Se ha utilizado para el diseño de los elementos gráfi-
cos 2D.
33
4.2.6. GitHub
Figura 23: Logotipo de GitHub
Fuente: github.com
GitHub es un control de versiones, una herramienta ideada para gestionar ágilmente los cambios
en el código fuente de los programas y poder revertirlos con facilidad. Mayormente importante
para proyectos en grupo, pero también muy útil para proyectos de un solo desarrollador.
34
5. Cuerpo del trabajo
Antes de comenzar con el desarrollo del videojuego, se han de definir todas las especificaciones
que este debe cumplir. Esto se conocería como diseño del videojuego, y agrupa las decisiones
como las mecánicas, el aspecto gráfico o los controles.
5.1. Diseño del juego
Nombre del juego
El nombre del juego será Babylon Heroes.
Concepto del juego
Babylon Heroes es un juego de rol en el que el jugador podrá moverse por un mundo abierto,
encontrándose con otros jugadores con los que debe cooperar para derrotar a los monstruos del
mundo.
Al matar enemigos el jugador obtiene puntos de experiencia, que sirve para que el jugador suba
de nivel, aumentando así sus valores de ataque, defensa y vida. Los enemigos pueden soltar po-
ciones o equipamiento que los jugadores pueden recoger. El objetivo del videojuego es conseguir
la máxima puntuación posible matando enemigos, ya que al morir se pierde todo el progreso y el
récord del jugador será guardado en una tabla de puntuaciones.
El juego tendrá una vista aérea (top-down), y los ataques de tanto los jugadores como los enemigos
serán disparos, proyectiles que comienzan en un punto inicial y recorren una distancia hasta un
punto final.
35
Género del juego
Babylon Heroes es un juego perteneciente al género MMORPG (juego de rol multijugador masivo
en línea).
Ciclo del juego
El flujo del juego es bastante sencillo, consta de las siguientes fases.
1. El jugador entra en el mundo.
2. El jugador explora el mundo con otros jugadores y combatiendo enemigos.
3. El jugador gana puntos, sube de nivel y recoge equipamiento.
4. El jugador muere, grabando su puntuación en la tabla de récords.
Una vez el jugador muere, si quiere seguir jugando debe entrar al mundo con un nuevo personaje
y repetir el ciclo.
Mecánicas
Las mecánicas son todo tipo de interacción entre el jugador y el mundo.
Movimiento: El jugador podrá moverse en ocho direcciones (arriba, abajo, izquierda, de-
recha, y las intermedias de estas cuatro). El mundo será un entorno 3D pero el jugador no
puede desplazarse por el eje Y.
Atacar: El jugador siempre posee un arma que puede disparar. Cada arma tiene distintos
valores en sus propiedades que la hace única (velocidad del proyectil, cadencia de disparo,
daño).
Magia: Cada arma tiene una habilidad mágica que puede ser utilizada cada poco tiempo.
Consume poder mágico del jugador.
36
Usar pociones: El jugador tiene acceso a pociones que le permiten regenerar vida o poder
mágico.
Recoger objetos: El jugador recogerá las armas que sueltan los enemigos al pasar por enci-
ma y recogerá pociones si no excede el límite de capacidad.
Mecánicas multijugador
Al ser un juego multijugador, la gran mecánica principal es la conexión entre todos los jugadores
y su interacción por el mundo. Todos los jugadores pueden ver el movimiento y acciones del resto
de jugadores en tiempo real.
Limitaciones del jugador
Las mecánicas del juego se rigen por unas limitaciones en el comportamiento del jugador o del
mundo del juego. Algunas de estas son:
El jugador cuenta con una barra de vida y otra de poder mágico. Al ser golpeado por pro-
yectiles enemigos perderá vida, si la barra se vacía el jugador morirá dando fin al ciclo del
juego. Usar habilidades mágicas consume poder mágico y, como es de suponer, si el jugador
no dispone de poder mágico no podrá usar la habilidad.
El jugador puede poseer hasta un límite de cinco pociones de vida y cinco pociones de magia
al mismo tiempo. Usar las pociones las elimina del inventario y añaden un porcentaje a las
barras de vida o magia del jugador.
Al obtener un arma de un enemigo el jugador pierde el arma que usaba anteriormente y no
podrá cambiar de arma hasta obtener una nueva.
Al ir derrotando enemigos se obtiene experiencia. Al superar ciertas cantidades el jugador
subirá de nivel, aumentando sus valores de daño y vida, además de rellenar completamente
sus barras de vida y magia.
37
Interfaz
La interfaz será lo mas sencilla posible para que el jugador pueda apreciar el mundo del juego sin
molestar. En la parte inferior se mostrarán las barras de vida y magia, además de la cantidad de
pociones de cada tipo. En la parte superior izquierda se mostrará la puntuación del jugador, y mas
a la derecha el nivel.
Mundo del juego
El mundo será un mundo abierto, donde el jugador pueda moverse a su placer, siempre y cuando
no se adentre en zonas para las que no está preparado, o probablemente morirá. El límite del mapa
está marcado por una zona circular que no se puede atravesar.
El juego consta de varios paisajes (desierto, campo, nieve), cada cual con un tipo de enemigos
distinto. También hay obstáculos como distintos tipos de árboles, rocas o murallas.
Todos los jugadores comienzan en la misma zona inicial, donde se encuentran los enemigos más
débiles, y han de desplazarse a las zonas mas peligrosas a medida que progresan, para así conseguir
mayor puntuación.
Controles
El juego requiere de teclado y ratón para sus controles.
Movimiento: Teclas WASD.
Habilidad mágica: Barra espaciadora.
Poción de vida: Tecla E.
Poción de magia: Tecla R.
Disparar: Click izquierdo. Mover el ratón sobre la pantalla del juego cambiará la dirección
en la que se apunta.
38
5.2. Planificación
Antes de comenzar con el desarrollo del videojuego se ha planificado el proyecto en iteraciones,
con un objetivo y varias tareas cada uno, que suele coincidir con una funcionalidad principal del
videojuegos.
Iteración 1: Implementar un servidor que admita la conexión y comunicación con múltiples
clientes. Implementar un prototipo con las mecánicas básicas del jugador.
Iteración 2: Implementar el motor 3D y un sistema de colisiones. Implementar un maneja-
dor de eventos.
Iteración 3: Implementar la inteligencia artificial de los enemigos. Diseñar los elementos
gráficos 2D. Implementar un sistema de combate y un sistema de equipamiento.
Iteración 4: Introducir los modelos 3D. Implementar la interfaz gráfica de usuario.
Iteración 5: Implementar el sistema de sonido. Implementar una base de datos.
Una vez planificadas las iteraciones, se procede al desarrollo del videojuego.
39
5.3. Iteración 1
5.3.1. Preparativos
El objetivo de esta iteración es tener una base para el videojuego final, se creará un servidor que
soporte la conexión simultanea de diferentes clientes.
Para ello se hace uso del framework node.js. Este es el núcleo de todo el proyecto, ya que será
el encargado del servidor. Está diseñado para construir aplicaciones en red escalables y permite
combinar todos los frameworks necesarios en el lado del servidor. Al contrario que la mayoría del
código JavaScript, no se ejecuta en un navegador, sino en el servidor.
Además, toda la lógica del videojuego sucederá en el servidor y esto no sería posible sin node.
Es decir, el juego no está almacenado en el cliente, el ciente simplemente visualiza los datos del
videojuego, que está sucediendo en el servidor.
Figura 24: Logotipo de Node
Fuente: nodejs.org
Después de instalar node.js desde su página web se ha de crear un directorio donde se almacenará
todo el proyecto, con la siguiente estructura.
40
Figura 25: Estructura de la aplicación
Fuente: propia
En la carpeta server, se incluirán todos los archivos requeridos por el servidor (código fuente
principalmente). En la carpeta client, se incluyen archivos requeridos por el cliente, generalmen-
te código HTML y JavaScript, pero también todas las imágenes que visualizará, entre otros. La
carpeta node_modules es el directorio donde se instalarán todos los módulos de node.
Finalmente el archivo main, es un fichero de código JavaScript y contiene el primer fragmento
que se ejecutará al iniciar la aplicación.
Para iniciar la aplicación se debe ir al directorio del archivo desde la consola de comandos y
ejecutar los siguiente.
node main.js
Ejemplo de "Hola Mundo"sobre un servidor web creado con node.js:
const http = require(’http ’);
const hostname = ’127.0.0.1 ’;
const port = 3000;
const server = http.createServer ((req , res) => {
res.statusCode = 200;
res.setHeader(’Content -Type ’, ’text/plain ’);
res.end(’Hola Mundo\n’);
});
server.listen(port , hostname , () => {
console.log(‘El servidor se esta ejecutando en http ://${hostname }:${
port}/‘);
});
41
Node.js es capaz de incorporar módulos de terceros que aporten nuevas funcionalidades. Todos los
frameworks utilizados en el lado del servidor son instalados a través del Node Package Manager
(npm).
Otro de los frameworks utilizados es express, una infraestructura de aplicaciones web Node.js
mínima y flexible que proporciona un conjunto sólido de características para las aplicaciones web,
y también móviles.
Para instalar express con node se utiliza el comando:
npm install express --save
Con express podemos enviar al usuario recursos como la página principal, donde tendrá lugar el
juego:
const express = require(’express ’);
const app = express ();
const serv = require(’http ’).Server(app);
app.get(’/’,function(req , res){
res.sendFile(__dirname + ’/client/index.html ’);
});
app.use(’/client ’, express.static(__dirname + ’/client ’));
serv.listen (2000);
Como se puede observar, el fichero index.html (el cual almacena la página principal del cliente) se
localiza en el directorio client mencionado anteriormente.
Una vez hecho esto ya se ha conseguido una infraestructura cliente/servidor que se puede iniciar
con el comando anterior, y al que se puede conectar con la dirección URL "http://localhost:2000/".
En este momento el cliente puede conectarse pero todavía falta una función importante, la co-
municación bidireccional. Para implementarla se hace uso del módulo socket.io, una tecnología
conocida como websockets.
Para instalarlo se hace uso del comando:
npm install --save socket.io
42
Socket.io aporta dos funcionalidades principales, enviar mensajes y escuchar mensajes. Tanto el
servidor como el cliente pueden enviar señales con cualquier tipo de datos o variables de JavaS-
cript. Un ejemplo del funcionamiento es el siguiente:
En el lado del servidor:
var mensaje = {
autor: "Pepito",
texto: "Hola"
};
socket.emit(’new -message ’, mensaje);
En el lado del cliente:
socket.on(’new -message ’, function(data) {
console.log(data);
});
En este caso el servidor crea un objeto con dos parámetros (autor y texto) y los envía con el
nombre de "new-message". El socket del cliente siempre que reciba una señal del tipo "new-
message.ejecutará una función en la que utiliza los parámetros recibidos (data).
El uso de los websockets es de extrema importancia ya que para el control del videojuego los
sockets registran los input del usuario. Cada vez que el usuario pulse una tecla de los controles, el
cliente hará un emit con la tecla pulsada, y lo mismo cuando deje de pulsarla. De esta manera el
servidor será consciente del estado de cada jugador (si está pulsando las teclas de mover, o si está
disparando, o incluso, a dónde apunta con el cursor del ratón).
Con todo esto ya preparado se comienza el desarrollo del juego en sí.
5.3.2. Bucle del juego
El bucle del juego, como su nombre indica, es un bucle que se repite múltiples veces por segundo
y en el que el juego actualiza los cambios en los datos del juego (posiciones, cantidades de vida,
etc).
43
El bucle del juego es el siguiente:
//GAME LOOP
const timeStep = 1 / 60;
setInterval(function (){
let entityPacks = Entity.getFrameUpdateData ();
let triggerPacks = Event.getFrameUpdateData ();
for(let i in SOCKET_LIST){
SOCKET_LIST[i].emit(’init ’, entityPacks.init , triggerPacks.init);
SOCKET_LIST[i].emit(’update ’, entityPacks.update , triggerPacks.update);
SOCKET_LIST[i].emit(’remove ’, entityPacks.remove , triggerPacks.remove);
if (SOCKET_LIST[i] && SOCKET_LIST[i]. toDelete){
delete SOCKET_LIST[i];
}
}
},1000 * timeStep);
// timestep^-1 times per second
Aunque parezca algo complicado, el proceso es bastante sencillo. Para empezar el bucle se repro-
duce 60 veces por segundo, esto es un estándar en el desarrollo de videojuegos (más es muchas
veces innecesario y menos da lugar a una dinámica muy pausada).
Dentro del bucle lo primero que sucede es getFrameUpdateData, esta función lo que hace es
actualizar todas las entidades del videojuego, como ya se ha explicado (si se han movido, si reciben
daño, si se han muerto, etc). Una entidad son todos los componentes del juego con vida propia,
en este caso los jugadores y los enemigos son entidades.
También en el juego existe el tipo de objeto trigger, estos son los componentes del juego sin
vida propia, en este caso los proyectiles son triggers. Normalmente los triggers no poseen cuerpo
físico (atraviesan todos los objetos), y cuentan con un área (generalmente circular o cuadrada) a
su alrededor que los activa cuando una entidad entra en contacto.
Tanto las entidades como los triggers cuentan con la función getFrameUpdateData con la que se
actualizan. Se guardan los valores necesarios en dos variables definidas con la instrucción let para
enviárselos al cliente.
44
A continuación se recorren en un bucle todos los sockets (o clientes) conectados. Para cada cliente
se ejecutan tres emit que envían un tipo distinto de datos:
1. Se envían datos de tipo init. Es decir, si se conecta un nuevo jugador, se enviará un paquete
con los datos de ese jugador a todos los jugadores, para que sea visualizado en todas las
pantallas de los jugadores. Lo mismo sucede cuando se crean enemigos o se disparan pro-
yectiles, si alguien dispara se crea un paquete con los datos de ese disparo para enviárselo
a todos los jugadores y que se dibuje en sus pantallas. Después de esto, se borran todos los
paquetes de tipo init para que no se creen duplicados.
2. Se envían los paquetes de tipo update, que actualizan la información de los triggers y enti-
dades ya existentes en la pantalla del jugador.
3. De la misma manera que los paquetes de tipo init, cuando un jugador se desconecta (o un
enemigo muere, o un disparo se desvanece) se crea un paquete de tipo remove con los
datos del objeto, para que el cliente lo borre de su pantalla y no permanezca en el juego
eternamente. Una vez enviados los paquetes de tipo remove, estos se eliminan, para no
intentar borrar algo que no existe en la siguiente iteración.
4. Finalmente, si ha habido alguna desconexión, este socket se elimina de la lista de sockets
conectados del servidor.
Este sistema de paquetes, aunque pueda parecer complicado, soluciona muchos problemas y aho-
rra mucho tiempo de ejecución ya que no se están enviando todos los datos constantemente. Es
decir, los paquetes de tipo init y remove, solo se envian una vez por cada entidad o trigger (cuando
se crean y cuando se destruyen), de esta manera el paquete de tipo update solo tiene que enviar los
datos necesarios.
5.3.3. Conexión y control del jugador
Al conectarse un jugador, el servidor registra el socket en una lista y crea una entidad de tipo
Player que añade al mundo. A esta entidad le asigna los valores generales de todas las entidades
(vida, posición, ángulo de rotación), además de valores para registrar los input del jugador para
saber qué teclas está pulsando en cada momento. También prepara al socket para ser borrado en el
momento de la desconexión.
45
var SOCKET_LIST = {};
const io = require(’socket.io ’)(serv ,{});
io.sockets.on(’connection ’, function(socket){
let id = Entity.getID();
socket.id = id;
SOCKET_LIST[socket.id] = socket;
Player.onConnect ();
socket.on(’disconnect ’,function (){
Player.onDisconnect ();
SOCKET_LIST[socket.id]. toDelete = true;
});
});
En el método Player.onConnect() es donde se le asignan todos los valores al jugador y se le añade
al mundo del juego. En el método Player.onDisconnect() se le elimina.
static onConnect () {
let player = new Player ();
socket.on(’keyPress ’, function (data) {
if (data.inputId === ’leftClick ’)
player.input.mouse = data.state;
else if (data.inputId === ’left ’)
player.input.a = data.state;
else if (data.inputId === ’down ’)
player.input.s = data.state;
else if (data.inputId === ’right ’)
player.input.d = data.state;
else if (data.inputId === ’up ’)
player.input.w = data.state;
else if (data.inputId === ’heal ’)
player.input.e = data.state;
else if (data.inputId === ’mana ’)
player.input.r = data.state;
else if (data.inputId === ’special ’)
player.input.special = data.state;
});
socket.on(’mouseMove ’, function (data) {
46
player.mousePosition.x = data.x;
player.mousePosition.y = data.y;
});
socket.emit(’init ’, Entity.getAllEntities (), allTriggers);
}
Como se puede observar se le asignan todos los controles para cuando el cliente haga emits de
cambios en los input tanto de teclado como de ratón. También al crearse el jugador se le envía un
paquete de tipo init, con todos los datos de entidades y triggers del juego. Esto hace que al entrar
el jugador visualice todos los elementos que han sido creados antes que él, y no ver un mundo
vacío al entrar.
Dicho de otra manera, cuando un jugador conecta (o se crea un enemigo o proyectil) se envía un
paquete init de este jugador a todos los otros jugadores conectados, pero este jugador que acaba
de conectar necesita recibir un paquete init de cada jugador (y enemigo y proyectil) que ya estaba
en el mundo antes que él.
El archivo index.html, y única página que verá el jugador, tiene la siguiente estructura:
<!DOCTYPE html >
<html lang="en">
<head >
<meta charset ="UTF -8">
<title >Babylon Heroes </title >
<link rel="icon" href=" favicon.png">
<link rel=" stylesheet" type="text/css" href="style.css">
<script src=" https :// cdnjs.cloudflare.com/ajax/libs/socket.io /2.1.1/
socket.io.js"></script >
<script src=" script.js"></script >
<meta name=" viewport" content =" width=device -width , initial -scale =1">
</head >
<body >
<header ></header >
<div >
<canvas id=" canvas"></canvas >
</div >
<footer ></footer >
<script >
loadCanvas ();
47
</script >
</body >
</html >
No hay mucho que destacar aquí ya que todo sucede desde el archivo script.js. Se puede observar
que la parte del cliente de socket.io se obtiene con el enlace de su página. En el cuerpo (body)
del documento se sitúa el elemento canvas en el que se visualizará el videojuego. No se le da
un tamaño ya que puede ocasionar errores y es mucho más conveniente darle el tamaño desde el
archivo de código JavaScript. Al cargar el documento HTML, se ejecuta la función loadCanvas
que inicia el canvas y el juego.
Finalmente está el código JavaScript de la parte del cliente. Lo primero es identificar el canvas y
darle un tamaño.
const _WIDTH = 1280,
_HEIGHT = 720;
var canvas , ctx;
var socket = io();
function loadCanvas () {
canvas = document.getElementById(’canvas ’);
canvas.width = _WIDTH;
canvas.height = _HEIGHT;
ctx = canvas.getContext (’2d’);
}
Para que el canvas dibuje lo que sucede en el mundo del juego del servidor, debe interpretar los
datos que recibe de los paquetes init, update y remove, almacenarlos, actualizarlos y dibujarlos
dentro de un bucle de juego en el lado del cliente.
Para almacenar los datos utiliza su propia versión de entidades y triggers que crea o modifica al
recibir los paquetes:
socket.on(’init ’, function(entitiesPack , triggersPack){
initPacks(entitiesPack , triggersPack);
});
socket.on(’update ’, function(entitiesPack , triggersPack){
updatePacks(entitiesPack , triggersPack);
48
});
socket.on(’remove ’, function(entitiesPack , triggersPack){
removePacks(entitiesPack , triggersPack);
});
Lo siguiente es el dibujado del canvas. Esto sucede en un bucle que borra y pinta en cada iteración
del juego. Con la siguiente función se limpiará el canvas, y se dibujará el mapa con la posición
relativa del cliente (selfID). El cliente siempre se ve situado en el centro del mapa, aunque se esté
moviendo. De esta manera no es el jugador sino todo lo demás lo que se mueve, en lo que se refiere
al dibujado:
setInterval(function (){
ctx.clearRect (0,0,_WIDTH ,_HEIGHT);
let x = _WIDTH /2 - Entity.list[selfID ]. position.x;
let y = _HEIGHT /2 - Entity.list[selfID ]. position.y;
ctx.drawImage(img.map , x, y);
for (let i in Entity.list){
drawObject(Entity.list[i], img.player);
};
for (let i in Trigger.list){
drawObject(Trigger.list[i], img.bullet);
};
}
La funcion drawObject es la siguiente:
function drawObject(e, imgType){
ctx.save();
let x = e.position.x - Entity.list[selfID ]. position.x + _WIDTH /2;
let y = e.position.y - Entity.list[selfID ]. position.y + _HEIGHT /2;
if(e.id == selfID){
x = _WIDTH /2;
y = _HEIGHT /2;
}
ctx.translate(x, y);
ctx.rotate ((e.lookingAt +90)*Math.PI/180);
49
ctx.drawImage(imgType , .imgType.width/2, -imgType.height /2);
ctx.restore ();
}
Por último solo queda añadir los controles del jugador en el lado del cliente. El servidor podía
recibir los mensajes de input pero se debe preparar al cliente para poder enviarlos. Los eventos de
teclado son los siguientes:
document.onkeydown = function(evt){
keyEvent(evt ,true);
}
document.onkeyup = function(evt){
keyEvent(evt ,false);
}
function keyEvent(evt , bool) {
if (evt.keyCode === 68) socket.emit(’keyPress ’, {inputId:’right ’,
state:bool}); //d
else if(evt.keyCode === 83) socket.emit(’keyPress ’, {inputId:’down ’,
state:bool}); //s
else if(evt.keyCode === 65) socket.emit(’keyPress ’, {inputId:’left ’,
state:bool}); //a
else if(evt.keyCode === 87) socket.emit(’keyPress ’, {inputId:’up ’,
state:bool}); //w
else if(evt.keyCode === 69) socket.emit(’keyPress ’, {inputId:’heal ’,
state:bool}); //e
else if(evt.keyCode === 82) socket.emit(’keyPress ’, {inputId:’mana ’,
state:bool}); //r
else if(evt.keyCode === 32) socket.emit(’keyPress ’, {inputId:’special ’,
state:bool}); // spacebar
}
Y los eventos de ratón:
document.onmousedown = function (){
mouseEvent(true);
}
document.onmouseup = function (){
mouseEvent(false);
}
document.onmousemove = function(evt){
mousePosition = getMousePosition(evt);
50
}
function mouseEvent(bool) {
socket.emit(’keyPress ’, {inputId:’leftClick ’, state:bool});
}
function getMousePosition(evt) {
let rect = canvas.getBoundingClientRect ();
return{
x: evt.clientX - rect.left ,
y: evt.clientY - rect.top ,
};
}
Con todo esto ya se dispone de una infraestructura cliente/servidor con el soporte multijugador de
un prototipo del videojuego.
Figura 26: Prototipo del juego con dos jugadores (triángulos azules) y múltiples disparos (triángulos rojos)
Fuente: propia
51
5.4. Iteración 2
Teniendo ya una buena base de la lógica del juego (movimiento, disparos, entidades), esta segunda
iteración está dedicada por un lado a la parte visual del cliente, y por otro lado a añadir algunas
mecánicas en el servidor. Se implementará un motor gráfico 3D y un sistema de colisiones.
5.4.1. Babylon
Babylon es el motor de dibujado 3D escogido para el videojuego. Para añadirlo al cliente se debe
enlazar en el fichero HTML:
<script src=" https :// cdn.babylonjs.com/babylon.max.js"></script >
Con el uso de Babylon ya no es necesario encargarse del dibujado de canvas, Babylon tiene una
función propia para el bucle de redibujado. Babylon aporta un elemento escena que dibuja todo
lo que se le añade. Por ejemplo, al editar la posición de un elemento añadido a la escena 3D de
Babylon, este se encarga de moverlo automáticamente en el canvas. Con lo que el iniciado del
canvas y el bucle quedaría de la siguiente manera:
function loadCanvas () {
canvas = document.getElementById(’canvas ’);
canvas.width = _WIDTH;
canvas.height = _HEIGHT;
engine = new BABYLON.Engine(canvas , true);
scene = createScene ();
engine.runRenderLoop(function (){
scene.render ();
});
}
52
Figura 27: Escena básica de Babylon
Fuente: propia
Al no añadir todavía los modelos 3D, en esta versión del juego los jugadores vendrán representados
por cajas blancas.
5.4.2. Motor de físicas p2js
Para implementar un motor de físicas se utiliza el módulo de node p2.js, se instala en el servidor
con el comando:
npm install p2
Para utilizarlo en el código se incluye de la siguiente manera:
var p2 = require(’p2 ’);
Este motor o librería de físicas permite añadir cuerpos cinemáticos a las entidades y crear cuerpos
sólidos para el mundo. Al ser un motor para físicas en dos dimensiones, se debe poner la gravedad
del mundo a valor cero, aquí moverse hacia arriba es lo mismo que moverse hacia los lados.
var world = new p2.World ({
53
gravity :[0, 0]
});
Para añadir un cuerpo a las entidades se ha de crear un tipo cuerpo, con una masa y posición
inicial, y una forma, que puede ser cuadrada, circular, etc:
self.circleBody = new p2.Body({
mass: 5,
position: [x, z]
});
self.circleShape = new p2.Circle ({ radius:self.radius });
self.circleBody.addShape(self.circleShape);
Para el movimiento de las entidades se modifica el valor velocidad de los cuerpos:
self.updateSpeed = function (){
if (self.input.d)
self.circleBody.velocity [0] = self.movSpeed;
else if (self.input.a)
self.circleBody.velocity [0] = -self.movSpeed;
else
self.circleBody.velocity [0] = 0;
if (self.input.w)
self.circleBody.velocity [1] = self.movSpeed;
else if (self.input.s)
self.circleBody.velocity [1] = -self.movSpeed;
else
self.circleBody.velocity [1] = 0;
if(self.circleBody.velocity [0] != 0 && self.circleBody.velocity [1] != 0){
let signX = Math.sign(self.circleBody.velocity [0]);
let signY = Math.sign(self.circleBody.velocity [1]);
self.circleBody.velocity [0] = signX * Math.sqrt(self.movSpeed * self.
movSpeed / 2);
self.circleBody.velocity [1] = signY * Math.sqrt(self.movSpeed * self.
movSpeed / 2);
}
};
En este fragmento de código se comprueban los input del jugador y el servidor modifica los valores
54
de velocidad según estos. También comprueba las direcciones diagonales.
Con las entidades ya preparadas para las colisiones, solo resta añadir elementos sólidos al mundo
(bloques que no se pueden mover, aunque estén en contacto con algun cuerpo que intente empu-
jarlos):
let staticBody = new p2.Body({mass:mass , position :[pX ,pZ]});
let bodyShape = new p2.Box({ height:d, width:w});
staticBody.addShape(bodyShape);
_World.addBody(staticBody);
En este caso se añade un bloque cuadrado de masa mass y de posición [px, pz], con una altura y
anchura d y w respectivamente.
5.4.3. Cargado del mundo
Para simplificar el diseño del mapa se ha utilizado la herramienta Tiled, que permite pintar mapas
de cuadrícula dados unos patrones de dibujo. En este caso se ha utilizado como herramienta para
generar la matriz de colisiones, una matriz de unos y ceros que el servidor interpretará para crear
bloques sólidos donde lea unos.
Figura 28: Ejemplo de uso de Tiled para crear la matriz de colisiones
Fuente: propia
55
Con esta simple cuadrícula se puede extraer la matriz de ceros y unos, que el servidor leerá de la
siguiente manera:
let y = map.blocks.length - 1;
for(let i in map.blocks){
for(let j in map.blocks[i]){
if(map.blocks[i][j] == 1){
pX = j * d + d/2;
pZ = y * w + w/2;
let staticBody = new p2.Body({mass:mass , position :[pX ,pZ]});
let bodyShape = new p2.Box({ height:d, width:w});
staticBody.addShape(bodyShape);
_World.addBody(staticBody);
}
}
y--;
}
De esta manera se consigue la posibilidad de editar el mapa de colisiones sin tener que modificar
el código fuente. El servidor, además de crear todos los bloques, los añade a una lista que mandará
al cliente para que este pueda dibujarlos.
El servidor también interpreta una matriz con el diseño del suelo del juego, que tiene más valores
que ceros y unos. El cliente recibe esta matriz y dibuja un plano con diferentes tipos de textura
para el suelo, según los valores de la matriz.
56
Figura 29: Estado del juego al final de la segunda iteración
Fuente: propia
57
5.5. Iteración 3
En la tercera iteración el trabajo se enfoca en la parte del servidor del juego. Se implementarán
enemigos, con una inteligencia básica, y un sistema de combate y armas. El único cambio que se
verá en el cliente será un aumento de cajas blancas debido a la introducción de los enemigos.
5.5.1. Inteligencia Artificial
Para el diseño de los enemigos se parte de la base de las entidades ya implementadas, los jugadores,
ya que comparten la mayoría de atributos. Se les debe implementar un comportamiento y una
manera de que aparezcan en el mundo.
El comportamiento de una inteligencia artificial viene controlado por una máquina de estados, un
sistema con entradas y salidas, que actuará de una manera u otra en función del estado.
var StateMachine = function (){
var self = {
activeState:’’,
previousState:’’,
}
self.setState = function(state){
previousState = this.activeState;
this.activeState = state;
state.onEnter ();
}
self.update = function (){
this.activeState ();
}
return self;
}
El código superior corresponde a una máquina de estados sencilla, esta almacena el estado actual
y anterior, ejecuta una función determinada al cambiar de estado (state.onEnter()), y actualiza el
58
estado actual.
Para este videojuego un enemigo consta de tres estados diferenciados:
Roam: Estado inicial del enemigo. Mientras no haya jugadores cercanos, el enemigo se
moverá aleatoriamente cerca del punto donde apareció. Si un jugador se acerca demasiado,
cambiará al siguiente estado.
FollowPlayer: Al ver a un jugador, el enemigo lo perseguirá atacándole con sus proyectiles,
sin embargo no lo sigue eternamente. Si el jugador se aleja lo suficiente, o el enemigo se
aleja demasiado de su punto inicial, este cambiará al siguiente estado.
ReturnToSpawn: Estado simple en el que el enemigo vuelve a su punto inicial, al llegar
cambia al estado roam para patrullar nuevamente.
También existe el estado muerto, al que el enemigo entra justo después de morir, pero no hace
nada, ya que está muerto.
5.5.2. Nidos de enemigos
Los nidos de enemigos son puntos en el mundo que generan un tipo concreto de enemigos. Se
crean al iniciar el mundo y tienen algunas limitaciones. Un nido de enemigos tiene un límite
de enemigos que controla al mismo tiempo, mientras esté en ese límite el nido no creará más
enemigos.
Los enemigos se crean aleatoriamente cada cierto tiempo, pero hay un mínimo de tiempo entre la
creación de cada enemigo; también si trascurre mucho tiempo sin crear un enemigo, se forzará a
crear uno.
Por último, si los jugadores eliminan todos los enemigos de un nido, este pasa a un estado de
regeneración, en el que debe descansar un periodo largo de tiempo hasta poder volver a generar
enemigos.
59
5.5.3. Diseño de las armas
Los enemigos sueltan armas al morir, que el jugador puede recoger para cambiar por la que posee.
Cada arma tiene valores de daño, rango (distancia que recorre), velocidad de proyectil, y cadencia
de disparo.
Figura 30: Armas en Babylon Heroes
Fuente: elaboración propia
Las armas disparan proyectiles, que se corresponden con triggers en la lógica del juego. Los trig-
gers tienen una forma dentro del motor de físicas, pero no tienen un cuerpo, no pueden empujar a
las entidades o a los otros proyectiles con los que entran en contacto. Al no tener cuerpo se crean
como tipo sensor.
self.sensorShape = new p2.Circle ();
self.sensorShape.sensor = true;
self.sensorBody = new p2.Body({ position :[x, z]});
self.sensorBody.addShape(self.sensorShape);
Cuando un trigger entra en contacto con una entidad, se dispara el método onTouch() del trigger,
en el caso de las armas hará daño a un jugador si es lanzado por un enemigo, o a un enemigo si es
lanzado por un jugador. También se prepara para ser borrado.
self.onTouch = function(entity){
if (entity.isPlayer){
if (self.isEnemy){
entity.recieveDamage(weapon.damage);
self.toRemove = true;
60
}
}else{
if (!self.isEnemy){
entity.recieveDamage(weapon.damage);
self.toRemove = true;
}
}
}
Para que el jugador dispare, el juego comprueba en cada momento si el jugadores está pulsando la
tecla de disparar, y si lo está haciendo, creará un proyectil desde el jugador.
self.shootingCheck = function (){
if (input.mouse && self.shootingCD) {
self.shootingCD = false;
self.shootBullet(self.lookingAt);
self.cooldownInterval = setInterval (() => {
self.shootingCD = true;
clearInterval(self.cooldownInterval);
}, self.weapon.cooldown);
}
}
En el fragmento de código superior, se comprueba si el jugador está pulsando el ratón para disparar,
y si ha pasado suficiente tiempo desde que se lanzó el último disparo. Si cumple las condiciones,
se crea una disparo hacia donde está apuntando el jugador self.shootBullet(self.lookingAt);. A
continuación se prepara un contador de tiempo, con una cadencia según el arma que esté usando
(self.weapon.cooldown. Se eliminará al cumplir el tiempo (clearInterval(self.cooldownInterval);),
y pondrá el disparo del jugador disponible de nuevo (self.shootingCD = true;).
Para que todo este sistema funcione, el juego cuenta con un Event Manager (o manejador de
eventos), que se encarga de comprobar si una entidad ha entrado en contacto con un áera de un
trigger.
5.5.4. Event Manager
Trigger.update = function(entities , blocks){
61
for(let t in Trigger.list){
// Triggers to entities
let trigger = Trigger.list[t];
for(let e in entities){
let entity = entities[e];
if(trigger.isTouching(entity)){
trigger.onTouch(entity);
}
};
// Bullets to blocks
if(trigger.isBullet){
blocks.forEach(block => {
if(trigger.isTouchingBlock(block)){
trigger.onTouchBlock ();
}
});
}
};
}
En cada iteración del bucle en el servidor, el Event Manager recorre las lista de todos los triggers y
comprueba si está con contacto con una entidad, de ser así dispara el trigger. También comprueba
si los trigger de tipo proyectil han entrado en contacto con algún bloque sólido, para así borrarlo.
El Event Manager también se encarga de agrupar los paquetes con todos los triggers en el mundo,
para enviarlos al cliente en cada iteración del bucle del juego. Además borra los triggers que han
sido listados para removerlos del juego.
Trigger.getUpdate = function (){
let pack = [];
for (let i in Trigger.list) {
let trigger = Trigger.list[i];
trigger.update ();
if (trigger.toRemove) {
trigger.removeFromGame ();
} else {
pack.push(trigger.getUpdatePack ());
}
}
return pack;
}
62
5.6. Iteración 4
Esta cuarta iteración se centra en pulir la parte gráfica del juego. Se sustituirán las cajas blancas
por modelos 3D de enemigos, y se implementará la interfaz gráfica de usuario, para que el jugador
tenga visión de otros elementos del juego.
5.6.1. De Blender a Babylon
Hay varias maneras de importar modelos a la escena 3D del juego, una de las mas cómodas es
utilizar un complemento de Blender, que permite convertir los modelos a un formato especial para
Babylon.
Figura 31: Instalación del convertidor de Blender a Babylon
Fuente: doc.babylonjs.com/resources/blender
63
Figura 32: Modelo 3D del jugador
Fuente: sketchfab.com - Autor: sketchfab.com/VitSh
Descargado el modelo, se carga en Blender y se convierte al formato de Babylon, resultando en
tres archivos. Estos archivos se deben incluir dentro del directorio client de la aplicación para que
el cliente puede acceder a ellos.
Figura 33: Resultado de la exportación del modelo 3D
Fuente: propia
5.6.2. Assets Manager
A la hora de cargar los modelos 3D de ficheros externos, la manera más eficiente es utilizar la
clase AssetsManager de Babylon. Este funciona por tareas, que se asignan al iniciar la escena, y
devolverá el recurso una vez haya sido cargado. De este modo se evitan problemas como intentar
dibujar un modelo 3D en la escena antes de estar listo, lo que lleva a errores.
Para implementarlo se modifica el fragmento de código que creaba la escena 3D:
function loadCanvas () {
64
canvas = document.getElementById(’canvas ’);
canvas.width = _WIDTH;
canvas.height = _HEIGHT;
engine = new BABYLON.Engine(canvas , true);
scene = createScene ();
var assetsManager = new BABYLON.AssetsManager(scene);
loadMeshes(assetsManager);
assetsManager.onFinish = function (){}
engine.runRenderLoop(function (){
scene.render ();
});
};
assetsManager.load();
}
Como se puede observar, en esta ocasión se crea el objeto assetsManager y se ejecuta la función
loadMeshes(), que se encarga de asignar las tareas de cargar los modelos 3D al AssetsManager.
Ya asignadas las tareas, se ejecuta el método load(), que pone a cargar todos los modelos de las
tareas.
Las tareas se asignan de la siguiente manera:
let wizard;
let wizardMeshTask = assetsManager.addMeshTask ("" ,"" ,"./ models /","
wizard.babylon ");
wizardMeshTask.onSuccess = function (task) {
wizard = wizardMeshTask.loadedMeshes [0];
}
El juego no se inicia hasta que se hayan cargado todos los modelos, así que durante el tiempo que
se tarda en cargar, AssetsManager inserta una pantalla de carga en el juego.
65
5.6.3. Interfaz gráfica de usuario
Para la implementación de la interfaz se ha incluido el módulo de BabylonGUI en el documento
HTML
<script src=" https :// preview.babylonjs.com/gui/babylon.gui.js"></script
>
La interfaz gráfica es bastante sencilla, simplemente se añaden texturas a la clase de Babylon
AdvancedDynamicTexture y se les asigna una posición en el canvas.
Con el módulo GUI de Babylon también se pueden escribir textos en la pantalla, lo que resulta
especialmente útil para indicar la puntuación y el nivel del jugador. Con el GUI también se indica
la cantidad de pociones de vida y magia que posee el jugador.
Figura 34: Barras de vida y magia del jugador
Fuente: elaboración propia
Ejemplo de cómo se incluye la barra de vida en la interfaz gráfica:
advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI
("UI");
let hpbar = new BABYLON.GUI.Image("", "textures/hpbar.png");
hpbar.height = 0.1;
hpbar.width = 0.4;
hpbar.top = "320px";
advancedTexture.addControl(hpbar);
66
Figura 35: Estado del juego al final de la cuarta iteración
Fuente: propia
67
5.7. Iteración 5
La quinta y última iteración consiste en pulir detalles jugables como valores en las estadísticas de
los enemigos y armas, además de añadir un pequeño sistema de sonido y una base de datos para
las puntuaciones.
En cuanto al equilibrado de estadísticas no hay mucho que comentar, consiste en ensayo y error,
modificar los valores de vida y daño de los enemigos, y las armas del jugador, a medida que esta
progresa en el juego.
5.7.1. Sistema de sonido
El sistema de sonido implementado también es bastante sencillo, se utiliza la clase de Babylon
Sound, para añadir una música de ambiente, o reproducir ciertos sonidos, por ejemplo cuando se
disparan proyectiles o se mueren los enemigos.
Música ambiente en bucle:
var music = new BABYLON.Sound(" Music", "music.wav", scene , null , { loop:
true , autoplay: true });
5.7.2. MongoDB
MongoDB es un sistema de base de datos NoSQL orientado a documentos de código abierto.
En lugar de guardar los datos en tablas, tal y como se hace en las bases de datos relacionales,
MongoDB guarda estructuras de datos BSON (una especificación similar a JSON) con un esquema
dinámico, haciendo que la integración de los datos en ciertas aplicaciones sea más fácil y rápida.
Figura 36: Logotipo de MongoDB
Fuente: codearmy.co
68
Se utilizará para almacenar la puntuación de los jugadores al morir. Para usar MongoDB se debe
instalar con la aplicación de escritorio y se debe iniciar desde la consola de comandos:
C:\ ProgramFiles\MongoDB\Server \3.0\ bin\mongod
Hacer esto es lo equivalente a hacer ’node main.js’ en node. MongoDB funciona por colecciones,
que están compuestas por documentos, que contienen los datos. Para iniciar una base de datos se
debe crear desde la consola de comandos:
para conectar con mongodb:
>mongo
para crear una base de datos:
>use miBaseDeDatos
para crear colecciones:
>db.createCollection (" puntuaciones ");
para incluir documentos:
>db.puntuaciones.insert ({ jugador :" pepito",puntuacion :"9000"});
El juego solo consta de una colección en la que almacena las puntuaciones de los jugadores, para
que el servidor tenga acceso se instala el módulo de MongoDB para node:
npm install mongodb --save
Finalmente para añadir documentos a las colecciones de la base de datos del juego se hace de la
siguiente manera:
var db = mongojs(’localhost :27017/ miBaseDeDatos ’, [’puntuaciones ’]);
db.puntuaciones.insert ({ jugador :" pedrito",puntuacion :"9999"});
El comando db.puntuaciones.find() devolverá todos los documentos de la colección puntuaciones,
y el servidor podrá enviárselos al cliente para que los visualice.
69
6. Conclusiones
Como conclusión general, se puede decir que se ha conseguido terminar el trabajo con éxito,
logrando el resultado propuesto: el desarrollo de un videojuego web usando tecnologías punteras
y prescindiendo de Flash. Los objetivos específicos también se han cumplido exitosamente.
Muchos estos objetivos estaban relacionados con la parte del desarrollo del videojuego, pero cada
uno se centraba en una funcionalidad o mecánica específica del videojuego, requiriendo el uso
de distintas tecnologías. Durante el desarrollo se han ido poniendo en práctica algunos conceptos
y tecnologías que se habían aprendido durante la carrera, mientras que se han ido adquiriendo
habilidades y conocimientos de manera autodidacta.
En definitiva, se han aplicado conocimientos de la titulación como la experiencia en los lenguajes
de programación (HTML, CSS, JS), y se ha profundizado en el aprendizaje de estas tecnologías
y de herramientas nuevas como los motores gráficos. Esto supone que lo estudiado en estos años
proporciona una base de conocimiento que permite aprender a usar nuevas tecnologías y aplicarlas
en diversos campos, como es en este caso el desarrollo de un videojuego.
Siendo sinceros, pienso que he acabado con un buen trabajo de fin de grado. Hacer un videojuego
es mucho para una sola persona pero creo que he podido hacer algo a la altura y digno de llamarse
trabajo de fin de grado. Reconozco que aunque sí es cierto que se puede mejorar, creo haber
cumplido los objetivos que se planteaban.
Si de algo me arrepiento es quizás de haberme lanzado a usar un motor gráfico 3D. Lograr un
acabado vistoso con un motor 3D es mucho más difícil que con un motor 2D, además de requerir
más trabajo; lo que ha resultado en un juego con modelos 3D sin animación, pero no estoy para
nada disgustado.
Estoy contento por haber aprendido todas estas tecnologías que no había usado durante la titula-
ción y estoy feliz por haber podido terminarlo.
70
7. Bibliografía
1. Adobe Flash Player. Disponible en línea: https://es.wikipedia.org/wiki/Adobe_Flash_Player
2. La cruzada contra Adobe Flash. Disponible en abc.es: https://bit.ly/2lzWXTQ
3. ¿Damos por muerto a Flash?. Disponible en xataka.com: https://bit.ly/2k7QxuK
4. Flash morirá en 2020. Disponible en xataka.com: https://bit.ly/2HazjSO
5. Saying goodbye to Flash in Chrome. Disponible en línea:
https://www.blog.google/products/chrome/saying-goodbye-flash-chrome/
6. Flash & The Future of Interactive Content. Disponible en línea:
https://theblog.adobe.com/adobe-flash-update/
7. ¿Qué ha pasado con las páginas de juegos flash?. Disponible en línea:
https://www.xataka.com/videojuegos/que-ha-pasado-con-las-paginas-de-juegos-flash
8. Videojuego de navegador. Disponible en línea:
https://es.wikipedia.org/wiki/Videojuego_de_navegador
9. HTML5. Disponible en línea: https://es.wikipedia.org/wiki/HTML5
10. JavaScript. Disponible en línea: https://es.wikipedia.org/wiki/JavaScript
11. Canvas (HTML). Disponible en línea: https://es.wikipedia.org/wiki/Canvas_(HTML)
12. Alien Hominid. Disponible en línea: https://en.wikipedia.org/wiki/Alien_Hominid
13. Case Study: Onslaught! Arena. Disponible en línea:
https://www.html5rocks.com/en/tutorials/casestudies/onslaught/
14. Página de newgrounds. Disponible en línea: https://www.newgrounds.com/
15. Página de minijuegos. Disponible en línea: https://www.minijuegos.com/
16. Understanding module.exports and exports in Node.js. Disponible en línea:
https://www.sitepoint.com/understanding-module-exports-exports-node-js/
17. Documentación de Babylon. Disponible en línea: https://doc.babylonjs.com/babylon101/
18. Documentación de LATEX. Disponible en línea: https://www.overleaf.com/learn/
71
19. Changing the Cursor with CSS for Better User Experience (or Fun). Disponible en línea:
https://css-tricks.com/using-css-cursors/
20. Página Sketchfab. Disponible en línea: https://sketchfab.com/
21. Tutorial de Raining Chain. Disponible en línea:
https://www.youtube.com/user/RainingChain/videos
22. Tutorial de Babylon. Disponible en línea:
https://www.youtube.com/playlist?list=PLS9MbmO_ssyCT1KHSi1GYX73ayv_9GusY
23. Documentación de VS Code. Disponible en línea:
https://code.visualstudio.com/docs?start=true
24. Página de node.js. Disponible en línea: https://nodejs.org/es/
25. Página de express. Disponible en línea: https://expressjs.com/es/
26. Página de socket.io. Disponible en línea: https://socket.io/
27. Página de Babylon. Disponible en línea: https://www.babylonjs.com/
28. Página de p2js. Disponible en línea: https://www.npmjs.com/package/p2
29. Página de mongodb. Disponible en línea: https://www.mongodb.com/es
30. PiskelApp. Disponible en línea: https://www.piskelapp.com/
31. Tiled. Disponible en línea: https://www.mapeditor.org/
32. Blender. Disponible en línea: https://www.blender.org/
33. BlenderExporter en GitHub. Disponible en línea:
https://github.com/BabylonJS/BlenderExporter
34. Repositorio GitHub del videojuego. Disponible en línea:
https://github.com/Juansanalme/tfg
72
8. Glosario
Flash: Normalmete se refiere al reproductor Adobe Flash Player.
Online: En línea.
NoSQL: Sistema de gestión de bases de datos que difiere del modelo clásico de base de
datos relacionales y que no usan SQL como lenguaje principal de consultas.
URL: Uniform Resource Locator (Localizador Uniforme de Recursos), dirección específica
de una página web.
3D: Tres dimensiones.
2D: Dos dimensiones.
Framework: Estructura conceptual y tecnológica de soporte definida, normalmente con
artefactos o módulos de software concretos.
Software: Conjunto de programas y rutinas que permiten a la computadora realizar deter-
minadas tareas.
PC: Ordenador personal.
Trigger: Componente de un videojuego que dispara una acción en concreta cuando entra en
contacto con un elemento.
Bullet Hell: Ïnfierno de balas", género de videojuego en el que se presentan cantidades
abrumadoras de proyectiles enemigos.
MMO: Género de videojuego multijugador masivo en línea (massively multiplayer online).
RPG: Role-Playing Game, juego de rol.
FPS: Puede referirse al género de videojuego de tiros en primera persona (First-Person
Shooter) o a frames por segundo, número imágenes consecutivas mostradas por segundo.
Plugin: Complemento que se relaciona con una aplicación para agregarle una función nueva
y generalmente muy específica.
GUI: Interfaz gráfica de usuario.
Input: Conjunto de datos que se introducen en un sistema o un programa informáticos.
73
Let: Instrucción de JavaScript que declara una variable de alcance local con ámbito de
bloque.
HTML: Lenguaje de marcado que se utiliza para el desarrollo de páginas de Internet. Se
trata de la siglas que corresponden a HyperText Markup Language.
JS: JavaScript, lenguaje de programación interpretado.
Canvas: Lienzo, elemento de HTML introducido en la versión 5.
Websocket: Tecnología que proporciona un canal de comunicación bidireccional.
Emit: Evento de socket.io para enviar mensajes.
74