Documentación técnica
Requerimientos de software
Descripción general
El programa cuenta de 4 módulos: cliente, servidor, editor y commons. El módulo de commons es utilizado por los otros 3 para cosas como los mapas, los sockets y la seri alización. A continuación se muestra en mayor detalle las responsabilidades de cada uno.
Módulo 1 - Cliente
Descripción general
El cliente fue hecho con SDL2. En primer lugar, al usuario se le muestra una pantalla de login. En la misma, se podrá conectar al servidor que quiera y luego crear una partida o elegir entre las existentes.
Una vez que la partida empiece, el jugador podrá ver la pantalla con el juego.
Cuando termine, se mostrará una tercer pantalla con el ranking.
Clases y Diagramas UML

Client_event_reciver: Es el hilo que se encarga de recibir las actualizaciones, deserializarlas y volverlas a meter en la cola protegida.

Client_event_sender: Es el hilo que se encarga de sacar de la cola bloqueando los comandos, serializador y mandarlos.

ManejadorEventos: se encarga de manejar la lógica de recibir eventos del teclado como avanzar, rotar, disparar, etc. Una vez que capta el evento, acá se crea el comando y se lo agrega en la cola de eventos.

Juego: es el hilo encargandor de realizar el loop, es decir, de limpiar, actualizar el modelo, renderizar y presentar. A su vez se encarga de
realizar el algoritmo de raycasting.

Módulo 2 - Servidor
Descripción general
El servidor se encarga de recibir a todos los clientes, crear y manejar las distintas partidas.
Clases y Diagramas UML
Cuando un cliente se conecta, se le mandan las partidas que no empezaron serializadas. Luego, se recibe si el cliente va a crear una nueva o unirse a la existente, y en base a eso se sigue la lógica.

Una vez que la partida está completa, se da inicio y el servidor la maneja de la siguiente manera:

Módulo 3 - Common
Descripción general
Este módulo consta de las cosas que son comunes tanto entre Servidor y Cliente, como con el Editor.
En este se encapsula la logica de las armas, los movimientos, el mapa, la serializacion entre otras cosas.
Clases y Diagramas UML
Serialización: para la serialización se creo la clase ISerializable, la cual luego extienden todas las clases que necesiten ser serializadas. Por ejemplo, los comandos, las actualizaciones y el mapa.

Módulo 4 - Editor
Descripción general
Esta aplicación está hecha con qt. Es un editor de mapas, donde el usuario puede crear y editar mapas para luego utilizar en el juego.
Clases y Diagramas UML
El editor consta de 3 clases principales.
-
MainWindow
Es la ventana principal de la aplicación. Extiende de QMainWindow. Esta es la encargada de crear a las otras dos clases que manejan, una la lista de tiles disponibles, y orta el mapa en sí. También tiene toda la lógica de crear un nuevo mapa, guardarlo y cargar un mapa existente.
-
MapWidget
Es el mapa en sí. Extiende de QWidget. Maneja los eventos de drop sobre el mapa guardando el tipo y la posición.
-
MapTilesList
Es la lista de los tiles disponibles para utilizar. Extiende la clase QListWidget. Consta de una lista de tiles, y maneja los eventos de drag y doble click sobre un tile.
El guardado y mostrar un mapa existente, se hacen fundamentalmente con la clase MapTranslator. Esta clase vive en el módulo commons. Lo que hace es que a partir de la clase Map la pasa a YAML y viceversa.
Descripción de archivos y protocolos
El protocolo desarrollado trata a los bytes para su lectura como big endian. Adem}ás, este protocolo serializa, en general, de la siguiente manera: primero se envia el tamanio del parámetro que se está serializando, y luego se serializa el parametro. Esto es porque, al ser binario, se requiere saber cuantos bytes corresponden a cada entidad para su deserializacion. De esta manera, se deserializa cada entidad de manera ordenada, evitando posibles errores.
A continuación se lista el protocolo según cada entidad serializada.
Jugador |
|
id jugador |
4 bytes |
size nombre |
4 bytes |
nombre |
size nombre bytes |
vida |
4 bytes |
arma actual |
4 bytes |
disparando |
4 bytes |
cantidad vidas |
4 bytes |
balas |
4 bytes |
size posicion |
4 bytes |
Posicion |
size posicion bytes |
size logro |
4 bytes |
Logro |
size logro bytes |
Posicion |
|
pixeles x |
4 bytes |
pixeles y |
4 bytes |
angulo (grados) |
4 bytes |
Logro |
|
enemigos matados |
4 bytes |
puntos tesoros |
4 bytes |
balas disparadas |
4 bytes |
ManejadorPartidas |
|
cant partidas |
4 bytes |
size nombre |
4 bytes |
nombre |
size nombre bytes |
Partida |
8 bytes |
Partida |
|
cant jugadores unidos |
4 bytes |
cant jugadores posibles |
4 bytes |
EstadoJuego |
|
cant jugadores |
4 bytes |
size jugador 1 |
4 bytes |
Jugador 1 |
size jugador 1 bytes |
….. |
……. |
size jugador n |
4 bytes |
Jugador n |
size jugador n bytes |
Mapa |
n bytes |
Mapa |
|
row size |
4 bytes |
col size |
4 bytes |
mapa(1,1) |
4 bytes |
mapa(1,2) |
4 bytes |
….. |
……. |
mapa(n,n-1) |
4 bytes |
mapa(n,n) |
4 bytes |
ContenedorElementos |
n bytes |
ContenedorElementos |
|
cant elementos |
4 bytes |
size item 1 |
4 bytes |
Item 1 |
size item 1 bytes |
….. |
……. |
size item n |
4 bytes |
Item n |
size item n bytes |
cant puertas |
4 bytes |
size puerta 1 |
4 bytes |
Puerta 1 |
size puerta 1 bytes |
….. |
……. |
size puerta n |
4 bytes |
Puerta n |
size puterta n bytes |
Puerta |
|
fila |
4 bytes |
columna |
4 bytes |
abierta |
4 bytes |
Posicion |
n bytes |
Item |
|
id |
4 bytes |
tipo |
4 bytes |
Posicion |
n bytes |
Apertura de puerta |
|
id jugador |
4 bytes |
id accion |
4 bytes |
Ataque |
|
id jugador |
4 bytes |
id accion |
4 bytes |
Cambio de arma |
|
id jugador |
4 bytes |
id accion |
4 bytes |
Crear partida |
|
id jugador |
4 bytes |
cantidad jugadores |
4 bytes |
size nombre partida |
4 bytes |
nombre partida |
size nombre partida bytes |
size ruta yaml |
4 bytes |
ruta yaml |
size ruta yaml bytes |
size nombre cliente |
4 bytes |
nombre cliente |
size nombre cliente bytes |
Movimiento |
|
id jugador |
4 bytes |
id tipo movimiento |
4 bytes |
Unirse a partida |
|
id accion |
4 bytes |
size nombre partida |
4 bytes |
nombre partida |
size nombre partida bytes |
size nombre cliente |
4 bytes |
nombre cliente |
size nombre cliente bytes |
Actualizacion Agarro Item |
|
id actualizacion |
4 bytes |
size item |
4 bytes |
Item |
size item bytes |
Actualizacion Agregar Item |
|
id actualizacion |
4 bytes |
size item |
4 bytes |
Item |
size item bytes |
Actualizacion Apertura Puerta |
|
id actualizacion |
4 bytes |
Puerta |
size item bytes |
Actualizacion Ataque |
|
id actualizacion |
4 bytes |
size jugador |
4 bytes |
Jugador |
size item bytes |
cant jugadores atacados |
4 bytes |
size jugador 1 |
4 bytes |
Jugador 1 |
size jugador 1 bytes |
….. |
……. |
size jugador n |
4 bytes |
Jugador n |
size jugador n bytes |
Actualizacion Cambio Arma |
|
id actualizacion |
4 bytes |
id jugador |
4 bytes |
arma actual |
size item bytes |
Actualizacion Inicio Partida |
|
id actualizacion |
4 bytes |
Estado juego |
n bytes |
Actualizacion Movimiento |
|
id actualizacion |
4 bytes |
Jugador |
n bytes |
Actualizacion Termino Partida |
|
id actualizacion |
4 bytes |
Estado juego |
n bytes |
Programas intermedios y de prueba
Originalmente, el programa lo realizamos en una sola aplicación simulando el cliente y el servidor, para no tener que tratar con la serialización. Una vez que eso estuvo más estable, involucramos los distintos hilos y la conexión mediante socket.