Videojuego Multijugador en línea sobre HTML5 Miquel Escribà del Arco Tutor: Joaquín Cerdá Boluda Trabajo Fin de Grado presentado en la Escuela Técnica Superior de Ingenieros de Telecomunicación de la Universitat Politècnica de València, para la obtención del Título de Graduado en Ingeniería de Tecnologías y Servicios de Telecomunicación Curso 2013-14 Valencia, 5 de septiembre de 2014 Resumen El proyecto consiste en el desarrollo de un videjuego multijugador para el que se ha utilizado el lenguaje de marcado HTML5 y el lenguaje de programación JavaScript. La idea consiste en la competición de cuatro jugadores que deben eliminar unos objetivos controlados por el juego. El foco del proyecto lo constituye el apartado técnico de su desarrollo, especialmente la comunicación entre cliente y servidor, para lo cual han debido implementarse cada uno de ellos. Resum El projecte consisteix en el desenvolupament d'un videjoc multijugador per al qual s'ha utilitzat el llenguatge de marcat HTML5 i i llenguatge de programació Javascript. La idea consisteix en la competició de quatre jugadors que han d'eliminar uns objectius controlats pel joc. El focus del projecte el constitueix l'apartat tècnic del seu desenvolupament, especialment la comunicació entre client i servidor, per a açò han hagut d'implementar-se cadascun d'ells. Abstract The project consists in the development of a multiplayer videogame for which has used the markup language HTML5 and the programming language Javascript. The idea consists in the competition of four players that have to destroy some objectives controlled by the game. The focus of the project constitutes it the technical aspects of its development, especially the communication between client and server. That is the reason for their development. Índice Capítulo 1. Introducción .......................................................................................................... 4 1.1 Motivaciones ................................................................................................................. 4 1.2 Objetivos ....................................................................................................................... 4 1.3 Planificación .................................................................................................................. 6 1.4 Contenido de la memoria .............................................................................................. 6 Capítulo 2. Contexto ................................................................................................................ 8 2.1 HTML ........................................................................................................................... 8 2.2 JavaScript ...................................................................................................................... 9 2.2.1 Declaración de variables y contextos .................................................................... 9 2.2.2 Tipos de variables y operaciones de igualdad ..................................................... 11 2.2.3 Herencia en JavaScript ........................................................................................ 13 2.2.4 Palabra reservada this .......................................................................................... 13 2.2.5 Otros aspectos a considerar de JavaScript ........................................................... 13 2.3 NODE.JS ..................................................................................................................... 14 2.3.1 Relación con JavaScript ...................................................................................... 14 2.3.2 Modelo de I/O. .................................................................................................... 14 2.3.3 Características de la implementación de Node.js ................................................ 15 2.4 HTML5 ....................................................................................................................... 15 2.5 WebSocket .................................................................................................................. 16 2.6 Canvas Engine ............................................................................................................. 16 2.7 Socket.io ...................................................................................................................... 17 Capítulo 3. Desarrollo ............................................................................................................ 18 3.1 Servidor ....................................................................................................................... 18 3.1.1 Desarrollo de la partida ....................................................................................... 18 3.1.2 Administración de la conexión ............................................................................ 29 3.2 Cliente ......................................................................................................................... 34 3.2.1 Preparación del documento HTML y clases propias ........................................... 34 3.2.2 Dibujado del juego con Canvas Engine .............................................................. 35 3.2.3 Administración de la conexión ............................................................................ 41 Capítulo 4. Resultados ........................................................................................................... 45 Capítulo 5. Líneas futuras y conclusiones.............................................................................. 49 5.1 Líneas futuras .............................................................................................................. 49 5.2 Conclusiones ............................................................................................................... 50 Capítulo 6. Bibliografía.......................................................................................................... 52 1 Índice de ilustraciones Ilustración 1. Código de colision() .............................................................................................. 19 Ilustración 2. Código de preparaciones de la partida .................................................................. 21 Ilustración 3. Código de start_game () ........................................................................................ 22 Ilustración 4. Código de update() ................................................................................................ 23 Ilustración 5. Código de sendupdate () ........................................................................................ 24 Ilustración 6. Código de finish_game() ....................................................................................... 24 Ilustración 7. Código de NPC.mover() ........................................................................................ 26 Ilustración 8. Código de Personaje.disparar() ............................................................................. 27 Ilustración 9. Parte diferente del código de proyectil.mover() .................................................... 28 Ilustración 10. Código de IA de los NPCs. ................................................................................. 29 Ilustración 11. Código de nueva conexión. Parte 1 ..................................................................... 30 Ilustración 12. Código de nueva conexión. Parte 2 ..................................................................... 30 Ilustración 13. Código de nueva conexión. Parte 3 ..................................................................... 31 Ilustración 14. Código de nueva conexión. Parte 4 ..................................................................... 31 Ilustración 15. Código de nueva conexión. Parte 5 ..................................................................... 32 Ilustración 16. Código de nueva conexión. Parte 6 ..................................................................... 32 Ilustración 17. Código de recepción de mensaje ......................................................................... 33 Ilustración 18. Código de desconexión de jugador ..................................................................... 34 Ilustración 19. Plantilla de spritesheet ........................................................................................ 35 Ilustración 20. Definición del Canvas ......................................................................................... 35 Ilustración 21. Código de createlocalplayer() ............................................................................. 36 Ilustración 22. Código de sendinput() ......................................................................................... 37 Ilustración 23. Código de shoot() ................................................................................................ 37 Ilustración 24. Código de mostrar_resultados() .......................................................................... 37 Ilustración 25. Código de ready() ................................................................................................ 38 Ilustración 26. Otro ejemplo de escuchador del teclado ............................................................. 38 Ilustración 27. Código de render(). Parte 1 ................................................................................. 39 Ilustración 28. Código de render(). Parte 2 ................................................................................. 40 Ilustración 29. Variables globales ............................................................................................... 41 Ilustración 30. Determinación de las acciones a realizar al recibir un mensaje .......................... 41 Ilustración 31. Mensaje INITIALIZE ......................................................................................... 42 Ilustración 32. Mensaje ANOTHER_PLAYER .......................................................................... 42 Ilustración 33. Mensaje SERVER_FULL ................................................................................... 42 2 Ilustración 34. Mensaje GAME_STATUS ................................................................................. 43 Ilustración 35. Mensaje UPDATE .............................................................................................. 43 Ilustración 36. Mensaje SHOOT ................................................................................................. 44 Ilustración 37. Vista del primer jugador conectado. ................................................................... 45 Ilustración 38. Vista del tercer jugador antes de comenzar la partida- ....................................... 46 Ilustración 39. Vista del tercer jugador una vez comenzada la partida ....................................... 46 Ilustración 40. Vista de intento de conexión con partida comenzada o servidor lleno ............... 47 Ilustración 41. Vista del jugador tres con todos los objetivos eliminados .................................. 47 Ilustración 42. Vista del jugador tres con la partida finalizada ................................................... 48 3 Capítulo 1. Introducción En este capítulo realizaremos una primera aproximación al proyecto a realizar, tanto por lo que respecta a las motivaciones personales que han llevado a la elección del mismo, como a la descripción de los objetivos a alcanzar en su desarrollo. También se aborda en este apartado la planificación y el proceso de desarrollo del trabajo realizado, así como una breve descripción de cada uno de los capítulos de la presente memoria. 1.1 Motivaciones La industria del videojuego es ya una realidad consolidada a pesar de su relativamente corta historia. Desde el primer Pong, de una entonces joven Atari en los años 70 (aunque falsamente considerado el primer videojuego de la historia, sí que marca el nacimiento de la industria), a las modernas videoconsolas y potentes ordenadores destinados al uso lúdico actuales, muchos géneros se han creado y se han olvidado desde entonces. Pero esta industria ha vivido en los últimos años una gran revolución de manos de los dispositivos móviles de gran potencia, los smartphones. Cada día los creadores ofrecen a las tiendas de Google y IOS cientos de aplicaciones nuevas, que generan grandes sumas de dinero gracias, no sólo a su venta, sino también a la incorporación de publicidad en juegos gratuitos, lo cual está trasladando el interés de las grandes compañías y de muchos jugadores a estas nuevas plataformas. La mayor parte de los nuevos videojuegos se basan en la posibilidad de la interconexión con otros jugadores o servicios en distintas partes del mundo. Es aquí donde las telecomunicaciones juegan un papel fundamental en el desarrollo de estas nuevas aplicaciones. 1.2 Objetivos El objetivo original de este trabajo era el realizar una aplicación para Android, pero en los primeros pasos del proyecto, siguiendo las indicaciones del tutor del trabajo, se decidió cambiar la plataforma por JavaScript y HTML5, lo que nos permite crear una aplicación accesible desde 4 cualquier navegador web, incluido el de los dispositivos móviles con relativamente poco esfuerzo adicional. Los requisitos originales eran crear un juego multijugador con arquitectura de cliente-servidor. El mapa tenía que ser creado por el juego a partir de un archivo de texto descriptivo. En este mapa debía haber personajes no controlados (NPC non-player character) que sirvieran como objetivo a los jugadores, que debían poder disparar a estos objetivos para conseguir puntos. El flujo de la partida es el siguiente: El servidor inicializa la partida. Los jugadores se conectan a la partida. Cuando hay al menos dos jugadores se esperará un tiempo corto para que se puedan conectar más jugadores. Una vez ha pasado este tiempo, la partida empieza. En este momento los jugadores pueden empezar a controlar su personaje. Una vez la partida ha comenzado, el servidor no acepta más jugadores. Los jugadores deben disparar a los objetivos y destruirlos. Una vez se han acabado los objetivos, el servidor envía un mensaje al cliente para indicar que la partida ha acabado, lo que hace que el cliente se desconecte. Después de enviar este mensaje, el servidor se reinicia, quedando listo para una nueva partida. Si durante la partida todos los jugadores se desconectan, el servidor también se reinicia. Otro de los puntos importantes para la garantía de un correcto funcionamiento del juego, es que todos los cálculos los realice el servidor y que el cliente no pueda realizar ningún cálculo que afecte a la partida. Sin embargo, no podemos enviar la información de un ciclo de actualización a cada iteración de los cálculos físicos, pues sería fácil saturar la conexión. Esto además ayudará a evitar que un jugador pueda utilizar un cliente modificado para hacer trampas, ya que el servidor sólo obtiene del cliente la intención de moverse y corregir cualquier error en el cliente debido a una pérdida de paquetes. Los cálculos físicos se ejecutan en el servidor a 60 frames per second (fps) pero la información se envía a tan solo 20 fps. Debido a esto, el cliente debe ejecutar una predicción a 60 fps que rellene el hueco entre envíos de información. Para esto, el cliente realiza los cálculos de movimiento de las entidades a partir del estado de movimiento que le envía el servidor. El servidor a su vez también realiza los mismos cálculos de movimiento y se los envía a los clientes, para corregir cualquier error que los clientes hayan cometido en la predicción del movimiento. La única función crítica que realizará el cliente será la de enviar al servidor lo que reciba del input del usuario, para que este pueda realizar sus cálculos. Este modelo en el que el servidor ejecuta los cálculos reales mientras que los clientes sólo realizan una predicción de los mismos, es utilizado en motores comerciales de éxito como el motor Source creado por Valve [1], una prestigiosa desarrolladora de videojuegos, y en juegos de éxito como Team Fortress 2 y Counter Strike: Global Offensive. 5 1.3 Planificación En primer lugar se procedió a la definición de los objetivos del trabajo, que como hemos mencionado anteriormente, consistían en la realización de un videojuego multijugador online en el que pudieran participar hasta cuatro jugadores que debían destruir mediante proyectiles objetivos controlados por el servidor. A continuación se dedicaron un par de semanas a la fase de documentación previa. Para ello se comenzó por realizar un acercamiento a la programación de videojuegos con JavaScript mediante la realización de un curso de Udacity [2], que ahondaba en los conceptos relativos a los videojuegos en tiempo real para JavaScript. A pesar de contener muchos fallos en cuanto al sistema de corrección automática de las tareas, resultó útil en cuanto a la gestión de memoria para las entidades. También se consultó el texto de Makzan, HTML5 Games Development by Example. Beginner's Guide [3] programación de videojuegos para JavaScript, en el capítulo dedicado a juegos multijugador online, lo que proporcionó los conocimientos necesarios para el diseño de los mensajes entre servidor y cliente. Seguidamente, y a lo largo de un mes aproximadamente, se procedió al desarrollo de la aplicación, es decir a la fase de programación, mediante la implementación tanto del cliente como del servidor, intercalando en el desarrollo de la escritura del código fases de pruebas que permitían comprobar que los cambios añadidos realizaban su función y que continuaba funcionado la parte ya desarrollada del código. 1.4 Contenido de la memoria Seguidamente pasamos a realizar un breve resumen del contenido de la presente memoria, que en su capítulo primero realiza la introducción de las motivaciones y de los objetivos del trabajo. En el segundo capítulo se realiza una aproximación al contexto tecnológico del trabajo a desarrollar; es decir, se ha tratado de hacer una sucinta explicación de las tecnologías utilizadas en su realización, tanto del lenguaje de programación JavaScript, como del lenguaje de marcado en sus versiones HTML y HTML5, así como de las distintas aplicaciones y librerías utilizadas: Node.js, Socket.io y Canvas Engine. El tercer capítulo se ha dedicado a la explicación del código fuente del proyecto. Para ello se ha desarrollado en primer lugar el funcionamiento del servidor, distinguiendo entre la parte relativa a la administración de la partida y la relativa a la conexión entre éste y los usuarios. En segundo lugar, se ha expuesto el desarrollo del código por lo que respecta al cliente. Para ello se ha distinguido entre lo relativo a la preparación de la página HTML y lo referente a la utilización de Canvas Engine para mostrar los gráficos, así como la administración de la conexión entre servidor y cliente. 6 En el cuarto capítulo se han abordado los resultados obtenidos en el desarrollo de la partida desde el punto de vista de los posibles jugadores. Para ello, se muestra el flujo del juego mediante diversas capturas de pantalla que ilustran lo que aparece en el navegador en cada momento de su proceso. El quinto capítulo aborda las posibles líneas futuras en que podría concretarse la mejora del proyecto en el caso de disponer de mayores conocimientos técnicos de aspectos como el desarrollo de gráficos o el diseño de viedojuegos, así como de más tiempo para la implementación de la aplicación web completa, de la adaptación de la aplicación a plataformas móviles o de la conectividad con las principales redes sociales. Por último, en este mismo capítulo también se abordan las conclusiones del trabajo, tanto lo relativo a lo que ha supuesto como experiencia de aplicación de conocimientos teóricos, como a la valoración de la comprobación de su funcionamiento o del uso de las diversas librerías utilizadas. 7 Capítulo 2. Contexto En este capítulo abordamos una aproximación al contexto tecnológico del trabajo realizado. Para ello se expone una escueta explicación de las tecnologías utilizadas en su realización: lenguaje de marcado en sus versiones HTML y HTML5, lenguaje de programación JavaScript, y las distintas aplicaciones y librerías utilizadas, como Node.js, Socket.io y Canvas Engine. 2.1 HTML HyperText Markup Language (HTML), o lenguaje de marcas de hipertexto, es un lenguaje de marcado diseñado para la composición de documentos en la web. A diferencia de un lenguaje de programación, un lenguaje de marcado es un conjunto de reglas y de marcas que un programa utiliza para interpretar un documento. Esto permite dar formato al texto, organizarlo, crear tablas, dividir el documento en partes, etc. y hasta mostrar otros tipos de datos, como imágenes. HTML está basado en el uso de de etiquetas, textos identificadores entre los símbolos “<” y “>”. Algunas de estas etiquetas se encuentran en parejas, conteniendo la segunda el símbolo “/” antes del texto identificador para indicar la etiqueta de cierre. Otras etiquetas se encuentran solas, como la etiqueta utilizada para mostrar imágenes, <img>. Los documentos HTML tienen dos partes principales. La primera de ellas, el encabezado, determinado por las etiquetas <head></head>, contiene información de la página, como el título o los scripts a utilizar. La otra parte es el cuerpo del documento, determinado por las etiquetas <body></body>, que contiene el texto, así como imágenes, formularios, objetos, etc. En definitiva, los elementos que se mostrarán en pantalla. Una de sus características más importantes es la posibilidad de definir enlaces, elementos que al ser activados por el usuario mediante el ratón indican al navegador que realice una petición de otro recurso web diferente. Esto nos permite crear sitios webs formados por diversas páginas manteniendo una gran facilidad de navegación. Las primeras versiones de HTML fueron creadas como borradores a principios de los noventa por Tim Berners-Lee [4], pero no llegaron a establecerse como estándares. A continuación, el Internet Engineering Task Force (IETF) creó un grupo de trabajo de HTML que desarrolló la 8
Description: