Skip to content

Commit

Permalink
Merge pull request #169 from SantiSev/dev_docs_SANTI
Browse files Browse the repository at this point in the history
Dev docs santi
  • Loading branch information
maxogod authored Jun 26, 2024
2 parents e4209f2 + 87eaddd commit 1c5e43c
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 4 deletions.
175 changes: 175 additions & 0 deletions docs/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,185 @@ El trabajo práctico se divide en cuatro partes principales:

## Game engine

### Physics Engine
Para el diseño de la _"physics engine"_, decidi basarme en la implementacion de fisicas del motor de juegos **Godot** donde llegue al siguiente planteo

##### Collision Objects
Todos los objects del juego son `CollisionObject`'s que consiste en objects con
```cpp
int hitbox_width; // el ancho del hitbox del object0
int hitbox_height; // el alto del hitbox del objecto
bool is_active = true; //el status para indicar si debe seguir detectando collisiones o no
```
[ un hitbox es utilizado para detectar colisiones entre los objetos de un juego ]

Para detectar dichas collisiones se utiliza los metodos protegidos `is_touching()` que tiene 2 variantes:
```cpp
/*
* This code determines which face of the calling
* CollisionObject instance (i.e., *this or self)
* is being touched by the other collision object.
*/
CollisionFace is_touching(const CollisionObject* other) const;

/*
* This code is identical to the is_touching method,
* but it returns a boolean value instead of a CollisionFace.
*/
bool is_touching_bool(const CollisionObject* other) const;
```
`CollisionFace` es un enum que indica de que lado fue tocado mi objecto con respecto al otro. Esto es util para diferenciar collisiones entre paredes, suelos, etc
Hay objectos (como en balas e items) donde no es importante saber donde fue tocado sino que solo importa que haya ocurrido una colision.
#### Abstraccion de Collision Object
```cpp
virtual void handle_colision(CollisionObject* other) = 0;
```
Este metodo es virtual puro porque CollisionObject no se debe poder instanciar en cualquier momento, el CollisionObject es la clase padre de todos los componentes del juego en donde todos sus clases hijos deben _handelear_ sus colisiones (dar la logica e indicar que ocurre cuando son colisionados). Hasta el momento hay solo 2 tipos:
- `Dynamic_body`
- `Static_body`

#### Collision Objects - Static Body
Static Body consiste en objetos que no se registra su movimiento y tampoco son movidos ó desaparecen.

#### Collision Objects - Dynamic Body
Dynamic Body consiste en objects que tienen movimiento (tanto horizontal como vertical), por lo tanto tienen el atributo:
```cpp
Vector2D velocity;
```
Como los dynamic bodies se mueven, se debe poder actualizar sus valores de posicion y/o velocidad, por lo tanto, tambien tienen una funcion virtual llamada:
```cpp
virtual void update_body();
```
Cuando se desee crear un objecto que se puede mover se debe implementar esta funcion sino nunca se actualizará sus valores de posicion / movimiento


### Collision Manager
Como vimos hasta el momento, todo es un CollisionObject, todo debe tener collisiones, etc. Pero aca viene la parte interesante ...

**¿Como se _detectan_ las colisiones?** --> A traves del `CollisionManager` !

El CollisionManager tiene como funcion recibir CollisionObjects, colocarlo en una grilla (luego explico como es la grilla) y activar los metodos de handle_collision cuando detecta una collision entre 2 objectos.

Principalmente detecta las colisiones de todos los objectos dinamicos. Si fuese a detectar cada colision de cada objeto, esto haria que el engine funcione muy pobre, por lo tanto decidí solo _trackear_ las colisiones de dynamicBodies y los StaticBodies solo estarán ahi para ser detectados.

#### Collision Manager - Grid & Deteccion de Collisiones
La grilla del collisionManager es de la siguiente manera:
```cpp
std::vector<std::vector<std::shared_ptr<CollisionObject>>> grid;
```

Es una matriz de shared pointers de CollisionObjects, en donde cada celda de la grilla indica
un pixel del juego. Al colocar un objecto en la grilla, en realidad estamos colocando en las posiciones desde (x ,y ) hasta (x+w , x+h ) shared pointers al mismo collision Object

Luego el CollisionManager realiza detecciones de los objetos dynamicos iterando alrededor de sus celdas y viendo si da nullpointer (no se detecto un objecto) o un shared pointer de otro CollisionObject (tanto statico o dynamico). Al detectar una collision realiza un **double dispatch** donde se llama los metodos de handeleo de collisiones de ambos objectos detectas.

#### Collision Manager - Detectar muchisimos bodies

Para nuestro juego, vamos a tener personajes (dynamic bodies) que disparan desde sus armas distintas bullets (tambien dynamic bodies), pero ... ¿El collision Manager no se va a realentizar al traquear tantos objetos? NO

con el metodo:
```cpp
void remove_inactive_bodies();
```
el collisionManager se ocupara de deshacerse de todos los bodies marcados como inactivos y serán quitadas del collisionManager.

#### Collision Manager - Usos

Se utiliza como atributo en la clase `Match` que lo utiliza para:
- Cargar las colisiones de plataformas del mapa de una partida
- Traquear los movimientos de players, enemigos, items & balas en la partida

Al cargar un mapa, se debe utilizar las funciones
```cpp
void add_object(std::shared_ptr<StaticBody> obj);

void prepare_map();
```
`add_object` permite agregar objectos estaticos al collisionManager y luego, la funcion `prepare_map` realiza una limpeza de las collisiones desactivando collisiones inecesarias entre objectos para evitar problemas de paredes invisibles y problemas raras debido a como se creo el custom map.
Al insertar un player/enemy/item a la partida ó respawnearlo, se debe avisar al collisionManager con la funcion:
```cpp
void track_dynamic_body(std::shared_ptr<DynamicBody> obj);
```

## Client

## Server

### Game Logic
Consiste en toda la logica relacionado con el juego en si, personajes, items, cheats, logica de las partidas, etc ...

#### Game Logic - Componentes

Para nuestra logica de juego, con el uso de lo creado en Physics_Engine logramos crear varios tipos de componentes de juego, a continuacion explicaremos brevemente cada uno y como funciona

**Characters**
Para el juego, decidimos crear 2 tipos de characteres, `Players` & `Enemies`

Los Players son los jugadores de las partidas y los clientes pueden ejecutar distitnos tipos de acciones como mover izquierda/derecha, saltar ó disparar

Luego, tenemos los Enemies, que consta de characteres que van a tratar de atacar players que detecten, su movimiento es limitado (solo pudiendo mover izquiera o derecha) y caminan por determinado rango de de espacio

la clases Player & Enemy son clases padre para luego poder crear los distintos tipos de players y enemies.

**Tipos de Players:**
- Jazz
- Spaz
- Lori

**Tipos de Enemies:**
- Mad Hatter
- Lizard Goon

**Weapons**

Todos los Jugadores tienen 4 tipos de armas, donde cada uno tiene distitnos tipos de daño, velocidad, frecuencia de disparo y cantidad de ammunicion maxima (con excepcion de una arma que tiene ammo infinita)

Al disparar distitnos player o enemigos, el player recibirá puntos y si logra matar a un enemigo o player recibe puntos bonus.

**Collectables**

Los collecatables son los items del juego, constan de estos tipos:

**Ammo:**

Items que recargan la ammunicion de las armas, de esta clase, hay 3 clases hijos que representan distitnos tipos de Ammo de Armas
- AmmoGunOne
- AmmoGunTwo
- AmmoGunThree

**Health_items:**

Items que recuperan vida de los players, hasta el momento solo tenemos el item:
- Meat

**Treasure:**

Items que da puntos al jugador que lo collecciona
item:
- Coin

**LA ZANAHORIA**

La zanahoria es un item _raro_ que no cae bajo una categoria en particular que hace lo siguiente.
Cuando un player lo colecciona, tiene 1/2 chance de ser intoxicado o tener invincibilidad por cierta cantidad de tiempo

- Al ser intoxicado, el jugador se moverá mas lento, no podrá saltar ni tampoco va a poder disparar.
- AL ser invincible al ser atacado por algun enemigo, player, etc no recibirá daño


**Platform**
El unico Platform hasta el momento, es el `Box_Platform` que consiste en bloques con Collision.


### GameLoop

El MatchesManager al recibir un mensaje del cliente de crear partida, lanza el hilo Match que es el game loop en sí, y añade al jugador a la partida. La Match puede continuar incluso si se van todos los jugadores, y pueden conectarse en cualquier momento cualquier jugador hasta que termine. La partida solo finaliza al llegar a cero el contador de partida, y tiene como límite una cantidad de jugadores que pueden unirse determinado por la configuracion del juego asignada en config.yaml.
Está configurada la partida para correr el juego a 60 fps, y se manda un estado de la partida por loop al cliente para poder renderizarla.
La partida además de los jugadores que pueden realizarse daño entre sí, contiene enemigos que patrullan de un lado a otro y realizan daño si haces contacto con ellos, aplicando también un knockback. Si los matas consigues puntos al igual que matar otro jugador (tambien puede configurarse estos valores en el confi.yaml).

El hilo principal main lanza la clase `Server`, luego Server lanza el hilo accepter, el aceptador de conexiones con los clientes por socket, y luego `Server` queda a la espera del input 'q' para cerrar todo gracefully.

El accepter lanza el hilo `MatchesManager`, y queda a la espera constante de clientes para ser aceptados. Al aceptar el socket del cliente se lo pasa al `MatchesManager` y a partir de él crea un nuevo "cliente".
Expand Down
4 changes: 0 additions & 4 deletions game_engine/physics_engine/collision_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,6 @@ void CollisionManager::update() { // create to update specific object
}
}

// create a method that removes all inactive objects from the grid
// and from the dynamic_bodies vector
// and then call this method from the update method

void CollisionManager::remove_inactive_bodies() {

if (dynamic_bodies.empty()) {
Expand Down

0 comments on commit 1c5e43c

Please sign in to comment.