eliminat sistema de colisió antic

This commit is contained in:
2026-04-06 23:05:22 +02:00
parent 6be93da929
commit 5414b0dfd4
9 changed files with 155 additions and 1157 deletions

View File

@@ -91,7 +91,15 @@ Se han renombrado las referencias de `JailDoctor's Dilemma` → `Projecte 2026`
- `checkFloor` para PASSABLE: solo aterriza si `foot_y_current <= tile_top` (pies estaban por encima). - `checkFloor` para PASSABLE: solo aterriza si `foot_y_current <= tile_top` (pies estaban por encima).
- `checkFloor` para slopes: solo aterriza si `foot_y_current <= slope_y` (pies por encima de la superficie). - `checkFloor` para slopes: solo aterriza si `foot_y_current <= slope_y` (pies por encima de la superficie).
- `isInsideAnySlope()`: si algún pie está por debajo de la superficie de cualquier slope que solape, bloquea TODOS los aterrizajes en slopes. Esto asegura que al hacer drop o saltar desde abajo, el jugador atraviesa toda la escalera de slopes sin quedarse pegado. - `isInsideAnySlope()`: si algún pie está por debajo de la superficie de cualquier slope que solape, bloquea TODOS los aterrizajes en slopes. Esto asegura que al hacer drop o saltar desde abajo, el jugador atraviesa toda la escalera de slopes sin quedarse pegado.
- **Pendiente:** tiles 5 (kill) y 6 (conveyor) no soportados aún en el nuevo motor. - **Kill tiles (tipo 5):** implementados en `TileCollider::touchesKillTile()`. Comprueba si el rectángulo del jugador solapa algún tile KILL. Se llama en `Player::update()` después del movimiento.
- **Motor antiguo eliminado:**
- `CollisionMap` reducido a wrapper mínimo: solo contiene `collision_tile_map_`, `conveyor_belt_direction_` y `TileCollider`.
- Eliminados de `CollisionMap`: enum `Tile` antiguo, `getTile()`, `getSlopeHeight()`, todas las listas de superficies (`bottom_floors_`, `top_floors_`, etc.), todos los `check*Surfaces()`, `initializeSurfaces()`, `collect*Tiles()`, `buildHorizontalLines()`, `set*Surfaces()`.
- Eliminados de `Room`: enum `Tile`, `getTile()`, `getSlopeHeight()`, `getTileSize()`, todos los `check*()` delegados, `getSlopeAtPoint()`.
- Eliminados de `utils.hpp/cpp`: structs `LineHorizontal`, `LineVertical`, `LineDiagonal`, `Line` y todos los `checkCollision` / `normalizeLine` que los usaban.
- `TilemapRenderer`: eliminado `renderDebugCollisionSurfaces()` (pintaba líneas de superficies). Modo debug (tecla 0) ahora renderiza el collision tilemap usando `collision.gif`.
- `TilemapRenderer::setAnimatedTiles()` ahora lee del `collision_tile_map` (valor 6 = conveyor) en vez de `CollisionMap::getTile()`.
- **Pendiente:** tile 6 (conveyor) no soportado aún en el nuevo motor de Player.
### Otros ### Otros
- Añadidos `desktop.ini` y `Thumbs.db` al `.gitignore`. - Añadidos `desktop.ini` y `Thumbs.db` al `.gitignore`.

View File

@@ -1,494 +1,8 @@
#include "collision_map.hpp" #include "collision_map.hpp"
#include <algorithm> // Para std::ranges::any_of #include <utility> // Para std::move
#ifdef _DEBUG
#include "core/system/debug.hpp" // Para Debug
#endif
#include "utils/defines.hpp" // Para Collision
// Constructor
CollisionMap::CollisionMap(std::vector<int> collision_tile_map, int conveyor_belt_direction) CollisionMap::CollisionMap(std::vector<int> collision_tile_map, int conveyor_belt_direction)
: collision_tile_map_(std::move(collision_tile_map)), : collision_tile_map_(std::move(collision_tile_map)),
conveyor_belt_direction_(conveyor_belt_direction), conveyor_belt_direction_(conveyor_belt_direction),
tile_collider_(collision_tile_map_) { tile_collider_(collision_tile_map_) {}
// Inicializa todas las superficies de colisión
initializeSurfaces();
}
// Inicializa todas las superficies de colisión
void CollisionMap::initializeSurfaces() {
setBottomSurfaces();
setTopSurfaces();
setLeftSurfaces();
setRightSurfaces();
setLeftSlopes();
setRightSlopes();
setAutoSurfaces();
}
// Devuelve el tipo de tile que hay en ese pixel
auto CollisionMap::getTile(SDL_FPoint point) const -> Tile {
const int ROW = static_cast<int>(point.y / TILE_SIZE);
const int COL = static_cast<int>(point.x / TILE_SIZE);
const int POS = (ROW * MAP_WIDTH) + COL;
return getTile(POS);
}
// Devuelve el tipo de tile que hay en ese indice (lee del collision_tile_map)
auto CollisionMap::getTile(int index) const -> Tile {
if (index < 0 || index >= static_cast<int>(collision_tile_map_.size())) {
return Tile::EMPTY;
}
switch (collision_tile_map_[index]) {
case 1:
return Tile::WALL;
case 2:
return Tile::PASSABLE;
case 3:
return Tile::SLOPE_L;
case 4:
return Tile::SLOPE_R;
case 5:
return Tile::KILL;
case 6:
return Tile::ANIMATED;
default:
return Tile::EMPTY;
}
}
// Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile
auto CollisionMap::getSlopeHeight(SDL_FPoint p, Tile slope) -> int {
// Calcula la base del tile
int base = ((p.y / TILE_SIZE) * TILE_SIZE) + TILE_SIZE;
#ifdef _DEBUG
Debug::get()->set("slope.BASE", std::to_string(base));
#endif
// Calcula cuanto se ha entrado en el tile horizontalmente
const int POS = (static_cast<int>(p.x) % TILE_SIZE); // Esto da un valor entre 0 y 7
#ifdef _DEBUG
Debug::get()->set("slope.POS", std::to_string(POS));
#endif
// Se resta a la base la cantidad de pixeles pos en funcion de la rampa
if (slope == Tile::SLOPE_R) {
base -= POS + 1;
#ifdef _DEBUG
Debug::get()->set("slope.result", "BASE_R=" + std::to_string(base));
#endif
} else {
base -= (TILE_SIZE - POS);
#ifdef _DEBUG
Debug::get()->set("slope.result", "BASE_L=" + std::to_string(base));
#endif
}
return base;
}
// === Queries de colisión ===
// Comprueba las colisiones con paredes derechas
auto CollisionMap::checkRightSurfaces(const SDL_FRect& rect) -> int { // NOLINT(readability-convert-member-functions-to-static)
for (const auto& s : right_walls_) {
if (checkCollision(s, rect)) {
return s.x;
}
}
return Collision::NONE;
}
// Comprueba las colisiones con paredes izquierdas
auto CollisionMap::checkLeftSurfaces(const SDL_FRect& rect) -> int { // NOLINT(readability-convert-member-functions-to-static)
for (const auto& s : left_walls_) {
if (checkCollision(s, rect)) {
return s.x;
}
}
return Collision::NONE;
}
// Comprueba las colisiones con techos
auto CollisionMap::checkTopSurfaces(const SDL_FRect& rect) -> int { // NOLINT(readability-convert-member-functions-to-static)
for (const auto& s : top_floors_) {
if (checkCollision(s, rect)) {
return s.y;
}
}
return Collision::NONE;
}
// Comprueba las colisiones punto con techos
auto CollisionMap::checkTopSurfaces(const SDL_FPoint& p) -> bool {
return std::ranges::any_of(top_floors_, [&](const auto& s) -> bool {
return checkCollision(s, p);
});
}
// Comprueba las colisiones con suelos
auto CollisionMap::checkBottomSurfaces(const SDL_FRect& rect) -> int { // NOLINT(readability-convert-member-functions-to-static)
for (const auto& s : bottom_floors_) {
if (checkCollision(s, rect)) {
return s.y;
}
}
return Collision::NONE;
}
// Comprueba las colisiones con conveyor belts
auto CollisionMap::checkAutoSurfaces(const SDL_FRect& rect) -> int { // NOLINT(readability-convert-member-functions-to-static)
for (const auto& s : conveyor_belt_floors_) {
if (checkCollision(s, rect)) {
return s.y;
}
}
return Collision::NONE;
}
// Comprueba las colisiones punto con conveyor belts
auto CollisionMap::checkConveyorBelts(const SDL_FPoint& p) -> bool {
return std::ranges::any_of(conveyor_belt_floors_, [&](const auto& s) -> bool {
return checkCollision(s, p);
});
}
// Comprueba las colisiones línea con rampas izquierdas
auto CollisionMap::checkLeftSlopes(const LineVertical& line) -> int { // NOLINT(readability-convert-member-functions-to-static)
for (const auto& slope : left_slopes_) {
const auto P = checkCollision(slope, line);
if (P.x != -1) {
return P.y;
}
}
return Collision::NONE;
}
// Comprueba las colisiones punto con rampas izquierdas
auto CollisionMap::checkLeftSlopes(const SDL_FPoint& p) -> bool {
return std::ranges::any_of(left_slopes_, [&](const auto& slope) -> bool {
return checkCollision(p, slope);
});
}
// Comprueba las colisiones línea con rampas derechas
auto CollisionMap::checkRightSlopes(const LineVertical& line) -> int { // NOLINT(readability-convert-member-functions-to-static)
for (const auto& slope : right_slopes_) {
const auto P = checkCollision(slope, line);
if (P.x != -1) {
return P.y;
}
}
return Collision::NONE;
}
// Comprueba las colisiones punto con rampas derechas
auto CollisionMap::checkRightSlopes(const SDL_FPoint& p) -> bool {
return std::ranges::any_of(right_slopes_, [&](const auto& slope) -> bool {
return checkCollision(p, slope);
});
}
// Obtiene puntero a slope en un punto (prioriza left_slopes_ sobre right_slopes_)
auto CollisionMap::getSlopeAtPoint(const SDL_FPoint& p) const -> const LineDiagonal* { // NOLINT(readability-convert-member-functions-to-static)
// Primero busca en rampas izquierdas
for (const auto& slope : left_slopes_) {
if (checkCollision(p, slope)) {
return &slope;
}
}
// Luego busca en rampas derechas
for (const auto& slope : right_slopes_) {
if (checkCollision(p, slope)) {
return &slope;
}
}
// No hay colisión con ninguna slope
return nullptr;
}
// === Helpers para recopilar tiles ===
// Helper: recopila tiles inferiores (muros sin muro debajo)
auto CollisionMap::collectBottomTiles() -> std::vector<int> { // NOLINT(readability-make-member-function-const)
std::vector<int> tile;
// Busca todos los tiles de tipo muro que no tengan debajo otro muro
// Hay que recorrer la habitación por filas (excepto los de la última fila)
for (int i = 0; i < (int)collision_tile_map_.size() - MAP_WIDTH; ++i) {
if (getTile(i) == Tile::WALL && getTile(i + MAP_WIDTH) != Tile::WALL) {
tile.push_back(i);
// Si llega al final de la fila, introduce un separador
if (i % MAP_WIDTH == MAP_WIDTH - 1) {
tile.push_back(-1);
}
}
}
// Añade un terminador
tile.push_back(-1);
return tile;
}
// Helper: recopila tiles superiores (muros o pasables sin muro encima)
auto CollisionMap::collectTopTiles() -> std::vector<int> { // NOLINT(readability-make-member-function-const)
std::vector<int> tile;
// Busca todos los tiles de tipo muro o pasable que no tengan encima un muro
// Hay que recorrer la habitación por filas (excepto los de la primera fila)
for (int i = MAP_WIDTH; i < (int)collision_tile_map_.size(); ++i) {
if ((getTile(i) == Tile::WALL || getTile(i) == Tile::PASSABLE) && getTile(i - MAP_WIDTH) != Tile::WALL) {
tile.push_back(i);
// Si llega al final de la fila, introduce un separador
if (i % MAP_WIDTH == MAP_WIDTH - 1) {
tile.push_back(-1);
}
}
}
// Añade un terminador
tile.push_back(-1);
return tile;
}
// Helper: recopila tiles conveyor belt
auto CollisionMap::collectConveyorTiles() -> std::vector<int> { // NOLINT(readability-make-member-function-const)
std::vector<int> tile;
// Busca todos los tiles de tipo conveyor
for (int i = MAP_WIDTH; i < (int)collision_tile_map_.size(); ++i) {
if (getTile(i) == Tile::ANIMATED) {
tile.push_back(i);
// Si llega al final de la fila, introduce un separador
if (i % MAP_WIDTH == MAP_WIDTH - 1) {
tile.push_back(-1);
}
}
}
// Añade un terminador si hay tiles
if (!tile.empty()) {
tile.push_back(-1);
}
return tile;
}
// Helper: construye lineas horizontales a partir de tiles consecutivos
void CollisionMap::buildHorizontalLines(const std::vector<int>& tiles, std::vector<LineHorizontal>& lines, bool is_bottom_surface) { // NOLINT(readability-convert-member-functions-to-static)
if (tiles.size() <= 1) {
return;
}
int i = 0;
while (i < static_cast<int>(tiles.size()) - 1) {
LineHorizontal line;
line.x1 = (tiles[i] % MAP_WIDTH) * TILE_SIZE;
// Calcula Y segun si es superficie inferior o superior
if (is_bottom_surface) {
line.y = ((tiles[i] / MAP_WIDTH) * TILE_SIZE) + TILE_SIZE - 1;
} else {
line.y = (tiles[i] / MAP_WIDTH) * TILE_SIZE;
}
int last_one = i;
i++;
// Encuentra tiles consecutivos
if (i < static_cast<int>(tiles.size())) {
while (tiles[i] == tiles[i - 1] + 1) {
last_one = i;
i++;
if (i >= static_cast<int>(tiles.size())) {
break;
}
}
}
line.x2 = ((tiles[last_one] % MAP_WIDTH) * TILE_SIZE) + TILE_SIZE - 1;
lines.push_back(line);
// Salta separadores
if (i < static_cast<int>(tiles.size()) && tiles[i] == -1) {
i++;
}
}
}
// === Métodos de generación de geometría ===
// Calcula las superficies inferiores
void CollisionMap::setBottomSurfaces() {
std::vector<int> tile = collectBottomTiles();
buildHorizontalLines(tile, bottom_floors_, true);
}
// Calcula las superficies superiores
void CollisionMap::setTopSurfaces() {
std::vector<int> tile = collectTopTiles();
buildHorizontalLines(tile, top_floors_, false);
}
// Calcula las superficies laterales izquierdas
void CollisionMap::setLeftSurfaces() { // NOLINT(readability-make-member-function-const)
std::vector<int> tile;
// Busca todos los tiles de tipo muro que no tienen a su izquierda un tile de tipo muro
// Hay que recorrer la habitación por columnas (excepto los de la primera columna)
for (int i = 1; i < MAP_WIDTH; ++i) {
for (int j = 0; j < MAP_HEIGHT; ++j) {
const int POS = ((j * MAP_WIDTH) + i);
if (getTile(POS) == Tile::WALL && getTile(POS - 1) != Tile::WALL) {
tile.push_back(POS);
}
}
}
// Añade un terminador
tile.push_back(-1);
// Recorre el vector de tiles buscando tiles consecutivos
// (Los tiles de la misma columna, la diferencia entre ellos es de mapWidth)
// para localizar las superficies
if ((int)tile.size() > 1) {
int i = 0;
do {
LineVertical line;
line.x = (tile[i] % MAP_WIDTH) * TILE_SIZE;
line.y1 = ((tile[i] / MAP_WIDTH) * TILE_SIZE);
while (tile[i] + MAP_WIDTH == tile[i + 1]) {
if (i == (int)tile.size() - 1) {
break;
}
i++;
}
line.y2 = ((tile[i] / MAP_WIDTH) * TILE_SIZE) + TILE_SIZE - 1;
left_walls_.push_back(line);
i++;
} while (i < (int)tile.size() - 1);
}
}
// Calcula las superficies laterales derechas
void CollisionMap::setRightSurfaces() { // NOLINT(readability-make-member-function-const)
std::vector<int> tile;
// Busca todos los tiles de tipo muro que no tienen a su derecha un tile de tipo muro
// Hay que recorrer la habitación por columnas (excepto los de la última columna)
for (int i = 0; i < MAP_WIDTH - 1; ++i) {
for (int j = 0; j < MAP_HEIGHT; ++j) {
const int POS = ((j * MAP_WIDTH) + i);
if (getTile(POS) == Tile::WALL && getTile(POS + 1) != Tile::WALL) {
tile.push_back(POS);
}
}
}
// Añade un terminador
tile.push_back(-1);
// Recorre el vector de tiles buscando tiles consecutivos
// (Los tiles de la misma columna, la diferencia entre ellos es de mapWidth)
// para localizar las superficies
if ((int)tile.size() > 1) {
int i = 0;
do {
LineVertical line;
line.x = ((tile[i] % MAP_WIDTH) * TILE_SIZE) + TILE_SIZE - 1;
line.y1 = ((tile[i] / MAP_WIDTH) * TILE_SIZE);
while (tile[i] + MAP_WIDTH == tile[i + 1]) {
if (i == (int)tile.size() - 1) {
break;
}
i++;
}
line.y2 = ((tile[i] / MAP_WIDTH) * TILE_SIZE) + TILE_SIZE - 1;
right_walls_.push_back(line);
i++;
} while (i < (int)tile.size() - 1);
}
}
// Encuentra todas las rampas que suben hacia la izquierda
void CollisionMap::setLeftSlopes() { // NOLINT(readability-make-member-function-const)
// Recorre la habitación entera por filas buscando tiles de tipo t_slope_l
std::vector<int> found;
for (int i = 0; i < (int)collision_tile_map_.size(); ++i) {
if (getTile(i) == Tile::SLOPE_L) {
found.push_back(i);
}
}
// El primer elemento es el inicio de una rampa. Se añade ese elemento y se buscan los siguientes,
// que seran i + mapWidth + 1. Conforme se añaden se eliminan y se vuelve a escudriñar el vector de
// tiles encontrados hasta que esté vacío
while (!found.empty()) {
LineDiagonal line;
line.x1 = (found[0] % MAP_WIDTH) * TILE_SIZE;
line.y1 = (found[0] / MAP_WIDTH) * TILE_SIZE;
int looking_for = found[0] + MAP_WIDTH + 1;
int last_one_found = found[0];
found.erase(found.begin());
for (int i = 0; i < (int)found.size(); ++i) {
if (found[i] == looking_for) {
last_one_found = looking_for;
looking_for += MAP_WIDTH + 1;
found.erase(found.begin() + i);
i--;
}
}
line.x2 = ((last_one_found % MAP_WIDTH) * TILE_SIZE) + TILE_SIZE - 1;
line.y2 = ((last_one_found / MAP_WIDTH) * TILE_SIZE) + TILE_SIZE - 1;
left_slopes_.push_back(line);
}
}
// Encuentra todas las rampas que suben hacia la derecha
void CollisionMap::setRightSlopes() { // NOLINT(readability-make-member-function-const)
// Recorre la habitación entera por filas buscando tiles de tipo t_slope_r
std::vector<int> found;
for (int i = 0; i < (int)collision_tile_map_.size(); ++i) {
if (getTile(i) == Tile::SLOPE_R) {
found.push_back(i);
}
}
// El primer elemento es el inicio de una rampa. Se añade ese elemento y se buscan los siguientes,
// que seran i + mapWidth - 1. Conforme se añaden se eliminan y se vuelve a escudriñar el vector de
// tiles encontrados hasta que esté vacío
while (!found.empty()) {
LineDiagonal line;
line.x1 = ((found[0] % MAP_WIDTH) * TILE_SIZE) + TILE_SIZE - 1;
line.y1 = (found[0] / MAP_WIDTH) * TILE_SIZE;
int looking_for = found[0] + MAP_WIDTH - 1;
int last_one_found = found[0];
found.erase(found.begin());
for (int i = 0; i < (int)found.size(); ++i) {
if (found[i] == looking_for) {
last_one_found = looking_for;
looking_for += MAP_WIDTH - 1;
found.erase(found.begin() + i);
i--;
}
}
line.x2 = (last_one_found % MAP_WIDTH) * TILE_SIZE;
line.y2 = ((last_one_found / MAP_WIDTH) * TILE_SIZE) + TILE_SIZE - 1;
right_slopes_.push_back(line);
}
}
// Calcula las superficies automaticas (conveyor belts)
void CollisionMap::setAutoSurfaces() {
std::vector<int> tile = collectConveyorTiles();
buildHorizontalLines(tile, conveyor_belt_floors_, false);
}

View File

@@ -1,123 +1,31 @@
#pragma once #pragma once
#include <SDL3/SDL.h> #include <vector>
#include <vector> // Para vector #include "game/gameplay/tile_collider.hpp"
#include "game/gameplay/tile_collider.hpp" // Para TileCollider
#include "utils/defines.hpp" // Para Tile::SIZE, Map::WIDTH, Map::HEIGHT
#include "utils/utils.hpp" // Para LineHorizontal, LineDiagonal, LineVertical
/** /**
* @brief Mapa de colisiones de una habitación * @brief Mapa de colisiones de una habitación
* *
* Responsabilidades: * Contiene el collision_tile_map (grid de tipos de tile) y el TileCollider
* - Almacenar la geometría de colisión (superficies, rampas, conveyor belts) * que proporciona queries de colisión directas contra el grid.
* - Generar geometría a partir del tilemap
* - Proporcionar queries de colisión para Player y otras entidades
* - Determinar tipo de tile en posiciones específicas
*/ */
class CollisionMap { class CollisionMap {
public: public:
// Enumeración de tipos de tile (para colisiones)
enum class Tile {
EMPTY,
WALL,
PASSABLE,
SLOPE_L,
SLOPE_R,
KILL,
ANIMATED
};
/**
* @brief Constructor
* @param collision_tile_map Mapa de colisiones por tile (0=vacío, 1=muro, 2=passable, 3=slope_l, 4=slope_r, 5=kill, 6=conveyor)
* @param conveyor_belt_direction Dirección de las cintas transportadoras (-1, 0, +1)
*/
CollisionMap(std::vector<int> collision_tile_map, int conveyor_belt_direction); CollisionMap(std::vector<int> collision_tile_map, int conveyor_belt_direction);
~CollisionMap() = default; ~CollisionMap() = default;
// Prohibir copia y movimiento
CollisionMap(const CollisionMap&) = delete; CollisionMap(const CollisionMap&) = delete;
auto operator=(const CollisionMap&) -> CollisionMap& = delete; auto operator=(const CollisionMap&) -> CollisionMap& = delete;
CollisionMap(CollisionMap&&) = delete; CollisionMap(CollisionMap&&) = delete;
auto operator=(CollisionMap&&) -> CollisionMap& = delete; auto operator=(CollisionMap&&) -> CollisionMap& = delete;
// --- Queries de tipo de tile ---
[[nodiscard]] auto getTile(SDL_FPoint point) const -> Tile; // Devuelve el tipo de tile en un punto (pixel)
[[nodiscard]] auto getTile(int index) const -> Tile; // Devuelve el tipo de tile en un índice del tilemap
// --- Queries de colisión con superficies ---
auto checkRightSurfaces(const SDL_FRect& rect) -> int; // Colisión con paredes derechas (retorna X)
auto checkLeftSurfaces(const SDL_FRect& rect) -> int; // Colisión con paredes izquierdas (retorna X)
auto checkTopSurfaces(const SDL_FRect& rect) -> int; // Colisión con techos (retorna Y)
auto checkTopSurfaces(const SDL_FPoint& p) -> bool; // Colisión punto con techos
auto checkBottomSurfaces(const SDL_FRect& rect) -> int; // Colisión con suelos (retorna Y)
// --- Queries de colisión con superficies automáticas (conveyor belts) ---
auto checkAutoSurfaces(const SDL_FRect& rect) -> int; // Colisión con conveyor belts (retorna Y)
auto checkConveyorBelts(const SDL_FPoint& p) -> bool; // Colisión punto con conveyor belts
// --- Queries de colisión con rampas ---
auto checkLeftSlopes(const LineVertical& line) -> int; // Colisión línea con rampas izquierdas (retorna Y)
auto checkLeftSlopes(const SDL_FPoint& p) -> bool; // Colisión punto con rampas izquierdas
auto checkRightSlopes(const LineVertical& line) -> int; // Colisión línea con rampas derechas (retorna Y)
auto checkRightSlopes(const SDL_FPoint& p) -> bool; // Colisión punto con rampas derechas
[[nodiscard]] auto getSlopeAtPoint(const SDL_FPoint& p) const -> const LineDiagonal*; // Obtiene puntero a slope en un punto
// --- Métodos estáticos ---
static auto getTileSize() -> int { return TILE_SIZE; } // Tamaño del tile en pixels
static auto getSlopeHeight(SDL_FPoint p, Tile slope) -> int; // Altura de rampa en un punto
// --- Getters ---
[[nodiscard]] auto getConveyorBeltDirection() const -> int { return conveyor_belt_direction_; }
[[nodiscard]] auto getTileCollider() const -> const TileCollider& { return tile_collider_; } [[nodiscard]] auto getTileCollider() const -> const TileCollider& { return tile_collider_; }
[[nodiscard]] auto getConveyorBeltDirection() const -> int { return conveyor_belt_direction_; }
// Getters para debug visualization [[nodiscard]] auto getCollisionTileMap() const -> const std::vector<int>& { return collision_tile_map_; }
[[nodiscard]] auto getBottomFloors() const -> const std::vector<LineHorizontal>& { return bottom_floors_; }
[[nodiscard]] auto getTopFloors() const -> const std::vector<LineHorizontal>& { return top_floors_; }
[[nodiscard]] auto getLeftWalls() const -> const std::vector<LineVertical>& { return left_walls_; }
[[nodiscard]] auto getRightWalls() const -> const std::vector<LineVertical>& { return right_walls_; }
[[nodiscard]] auto getLeftSlopes() const -> const std::vector<LineDiagonal>& { return left_slopes_; }
[[nodiscard]] auto getRightSlopes() const -> const std::vector<LineDiagonal>& { return right_slopes_; }
[[nodiscard]] auto getConveyorBeltFloors() const -> const std::vector<LineHorizontal>& { return conveyor_belt_floors_; }
private: private:
// --- Constantes --- std::vector<int> collision_tile_map_;
static constexpr int TILE_SIZE = ::Tile::SIZE; // Tamaño del tile en pixels int conveyor_belt_direction_;
static constexpr int MAP_WIDTH = ::Map::WIDTH; // Ancho del mapa en tiles TileCollider tile_collider_;
static constexpr int MAP_HEIGHT = ::Map::HEIGHT; // Alto del mapa en tiles
// --- Datos de la habitación ---
std::vector<int> collision_tile_map_; // Mapa de colisiones por tile
int conveyor_belt_direction_; // Dirección de conveyor belts
TileCollider tile_collider_; // Sistema de colisión por tiles
// --- Geometría de colisión ---
std::vector<LineHorizontal> bottom_floors_; // Superficies inferiores (suelos)
std::vector<LineHorizontal> top_floors_; // Superficies superiores (techos)
std::vector<LineVertical> left_walls_; // Paredes izquierdas
std::vector<LineVertical> right_walls_; // Paredes derechas
std::vector<LineDiagonal> left_slopes_; // Rampas que suben hacia la izquierda
std::vector<LineDiagonal> right_slopes_; // Rampas que suben hacia la derecha
std::vector<LineHorizontal> conveyor_belt_floors_; // Superficies automáticas (conveyor belts)
// --- Métodos privados de generación de geometría ---
void initializeSurfaces(); // Inicializa todas las superficies de colisión
// Helpers para recopilar tiles
auto collectBottomTiles() -> std::vector<int>; // Tiles con superficie inferior
auto collectTopTiles() -> std::vector<int>; // Tiles con superficie superior
auto collectConveyorTiles() -> std::vector<int>; // Tiles conveyor belt
// Construcción de geometría
static void buildHorizontalLines(const std::vector<int>& tiles, std::vector<LineHorizontal>& lines, bool is_bottom_surface);
void setBottomSurfaces(); // Calcula superficies inferiores
void setTopSurfaces(); // Calcula superficies superiores
void setLeftSurfaces(); // Calcula paredes izquierdas
void setRightSurfaces(); // Calcula paredes derechas
void setLeftSlopes(); // Calcula rampas izquierdas
void setRightSlopes(); // Calcula rampas derechas
void setAutoSurfaces(); // Calcula conveyor belts
}; };

View File

@@ -31,7 +31,7 @@ Room::Room(const std::string& room_path, std::shared_ptr<Scoreboard::Data> data)
// Crea el renderizador del tilemap (necesita tile_map_, tile_set_width_, surface_, bg_color_, conveyor_belt_direction_) // Crea el renderizador del tilemap (necesita tile_map_, tile_set_width_, surface_, bg_color_, conveyor_belt_direction_)
tilemap_renderer_ = std::make_unique<TilemapRenderer>(tile_map_, tile_set_width_, surface_, bg_color_, conveyor_belt_direction_); tilemap_renderer_ = std::make_unique<TilemapRenderer>(tile_map_, tile_set_width_, surface_, bg_color_, conveyor_belt_direction_);
tilemap_renderer_->initialize(collision_map_.get()); // Inicializa (crea map_surface, pinta tiles, busca animados) tilemap_renderer_->initialize(room->collision_tile_map);
Screen::get()->setBorderColor(border_color_); // Establece el color del borde Screen::get()->setBorderColor(border_color_); // Establece el color del borde
} }
@@ -96,7 +96,7 @@ void Room::renderItems() {
#ifdef _DEBUG #ifdef _DEBUG
// Redibuja el mapa (para actualizar modo debug) // Redibuja el mapa (para actualizar modo debug)
void Room::redrawMap() { void Room::redrawMap() {
tilemap_renderer_->redrawMap(collision_map_.get()); tilemap_renderer_->redrawMap(collision_map_->getCollisionTileMap());
} }
// Actualiza animaciones sin mover enemigos (para editor de mapas) // Actualiza animaciones sin mover enemigos (para editor de mapas)
@@ -123,7 +123,7 @@ void Room::setTile(int index, int tile_value) {
void Room::setBgColor(Uint8 color) { void Room::setBgColor(Uint8 color) {
bg_color_ = color; bg_color_ = color;
tilemap_renderer_->setBgColor(color); tilemap_renderer_->setBgColor(color);
tilemap_renderer_->redrawMap(collision_map_.get()); tilemap_renderer_->redrawMap(collision_map_->getCollisionTileMap());
} }
// Cambia colores de items en vivo (para editor) // Cambia colores de items en vivo (para editor)
@@ -181,99 +181,14 @@ auto Room::getRoom(Border border) -> std::string { // NOLINT(readability-conver
} }
} }
// Devuelve el tipo de tile que hay en ese pixel
auto Room::getTile(SDL_FPoint point) -> Tile { // NOLINT(readability-convert-member-functions-to-static)
// Delega a CollisionMap y convierte el resultado
const auto COLLISION_TILE = collision_map_->getTile(point);
return static_cast<Tile>(COLLISION_TILE);
}
// Devuelve el tipo de tile en un índice del tilemap
auto Room::getTile(int index) -> Tile { // NOLINT(readability-convert-member-functions-to-static)
// Delega a CollisionMap y convierte el resultado
const auto COLLISION_TILE = collision_map_->getTile(index);
return static_cast<Tile>(COLLISION_TILE);
}
// Indica si hay colision con un enemigo a partir de un rectangulo
auto Room::enemyCollision(SDL_FRect& rect) -> bool { auto Room::enemyCollision(SDL_FRect& rect) -> bool {
return enemy_manager_->checkCollision(rect); return enemy_manager_->checkCollision(rect);
} }
// Indica si hay colision con un objeto a partir de un rectangulo
auto Room::itemCollision(SDL_FRect& rect) -> bool { auto Room::itemCollision(SDL_FRect& rect) -> bool {
return item_manager_->checkCollision(rect); return item_manager_->checkCollision(rect);
} }
// Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile
auto Room::getSlopeHeight(SDL_FPoint p, Tile slope) -> int {
// Delega a CollisionMap (método estático)
const auto COLLISION_TILE = static_cast<CollisionMap::Tile>(slope);
return CollisionMap::getSlopeHeight(p, COLLISION_TILE);
}
// === Métodos de colisión (delegados a CollisionMap) ===
// Comprueba las colisiones con paredes derechas
auto Room::checkRightSurfaces(const SDL_FRect& rect) -> int {
return collision_map_->checkRightSurfaces(rect);
}
// Comprueba las colisiones con paredes izquierdas
auto Room::checkLeftSurfaces(const SDL_FRect& rect) -> int {
return collision_map_->checkLeftSurfaces(rect);
}
// Comprueba las colisiones con techos
auto Room::checkTopSurfaces(const SDL_FRect& rect) -> int {
return collision_map_->checkTopSurfaces(rect);
}
// Comprueba las colisiones punto con techos
auto Room::checkTopSurfaces(const SDL_FPoint& p) -> bool {
return collision_map_->checkTopSurfaces(p);
}
// Comprueba las colisiones con suelos
auto Room::checkBottomSurfaces(const SDL_FRect& rect) -> int {
return collision_map_->checkBottomSurfaces(rect);
}
// Comprueba las colisiones con conveyor belts
auto Room::checkAutoSurfaces(const SDL_FRect& rect) -> int {
return collision_map_->checkAutoSurfaces(rect);
}
// Comprueba las colisiones punto con conveyor belts
auto Room::checkConveyorBelts(const SDL_FPoint& p) -> bool {
return collision_map_->checkConveyorBelts(p);
}
// Comprueba las colisiones línea con rampas izquierdas
auto Room::checkLeftSlopes(const LineVertical& line) -> int {
return collision_map_->checkLeftSlopes(line);
}
// Comprueba las colisiones punto con rampas izquierdas
auto Room::checkLeftSlopes(const SDL_FPoint& p) -> bool {
return collision_map_->checkLeftSlopes(p);
}
// Comprueba las colisiones línea con rampas derechas
auto Room::checkRightSlopes(const LineVertical& line) -> int {
return collision_map_->checkRightSlopes(line);
}
// Comprueba las colisiones punto con rampas derechas
auto Room::checkRightSlopes(const SDL_FPoint& p) -> bool {
return collision_map_->checkRightSlopes(p);
}
// Obtiene puntero a slope en un punto
auto Room::getSlopeAtPoint(const SDL_FPoint& p) const -> const LineDiagonal* {
return collision_map_->getSlopeAtPoint(p);
}
// Carga una habitación desde un archivo YAML (delegado a RoomLoader) // Carga una habitación desde un archivo YAML (delegado a RoomLoader)
auto Room::loadYAML(const std::string& file_path, bool verbose) -> Data { // NOLINT(readability-convert-member-functions-to-static) auto Room::loadYAML(const std::string& file_path, bool verbose) -> Data { // NOLINT(readability-convert-member-functions-to-static)
return RoomLoader::loadYAML(file_path, verbose); return RoomLoader::loadYAML(file_path, verbose);

View File

@@ -10,9 +10,7 @@
#include "game/entities/item.hpp" // Para ItemData #include "game/entities/item.hpp" // Para ItemData
#include "game/gameplay/scoreboard.hpp" // Para Scoreboard::Data #include "game/gameplay/scoreboard.hpp" // Para Scoreboard::Data
#include "utils/defines.hpp" // Para Tile::SIZE, Map::WIDTH, Map::HEIGHT #include "utils/defines.hpp" // Para Tile::SIZE, Map::WIDTH, Map::HEIGHT
#include "utils/utils.hpp" // Para LineHorizontal, LineDiagonal, LineVertical class Surface;
class Sprite; // lines 12-12
class Surface; // lines 13-13
class EnemyManager; class EnemyManager;
class ItemManager; class ItemManager;
class CollisionMap; class CollisionMap;
@@ -30,114 +28,84 @@ class Room {
NONE = 4 NONE = 4
}; };
enum class Tile {
EMPTY,
WALL,
PASSABLE,
SLOPE_L,
SLOPE_R,
KILL,
ANIMATED
};
struct Data { struct Data {
std::string number; // Numero de la habitación std::string number;
Uint8 bg_color{0}; // Color de fondo de la habitación Uint8 bg_color{0};
Uint8 border_color{0}; // Color del borde de la pantalla Uint8 border_color{0};
Uint8 item_color1{12}; // Color 1 para los items de la habitación Uint8 item_color1{12};
Uint8 item_color2{6}; // Color 2 para los items de la habitación Uint8 item_color2{6};
std::string upper_room; // Identificador de la habitación que se encuentra arriba std::string upper_room;
std::string lower_room; // Identificador de la habitación que se encuentra abajo std::string lower_room;
std::string left_room; // Identificador de la habitación que se encuentra a la izquierda std::string left_room;
std::string right_room; // Identificador de la habitación que se encuentra a la derecha std::string right_room;
std::string tile_set_file; // Imagen con los gráficos para la habitación std::string tile_set_file;
int conveyor_belt_direction{0}; // Sentido en el que arrastran las superficies automáticas de la habitación int conveyor_belt_direction{0};
std::vector<int> tile_map; // Índice de los tiles a dibujar en la habitación (embebido desde YAML) std::vector<int> tile_map;
std::vector<int> collision_tile_map; // Mapa de colisiones por tile (0=vacío, 1=sólido) std::vector<int> collision_tile_map;
std::vector<Enemy::Data> enemies; // Listado con los enemigos de la habitación std::vector<Enemy::Data> enemies;
std::vector<Item::Data> items; // Listado con los items que hay en la habitación std::vector<Item::Data> items;
}; };
// Constructor y destructor // Constructor y destructor
Room(const std::string& room_path, std::shared_ptr<Scoreboard::Data> data); Room(const std::string& room_path, std::shared_ptr<Scoreboard::Data> data);
~Room(); // NOLINT(modernize-use-equals-default, performance-trivially-destructible) -- defined in .cpp for unique_ptr with forward declarations ~Room(); // NOLINT(modernize-use-equals-default, performance-trivially-destructible)
// --- Funciones --- // --- Funciones ---
[[nodiscard]] auto getNumber() const -> const std::string& { return number_; } // Devuelve el numero de la habitación [[nodiscard]] auto getNumber() const -> const std::string& { return number_; }
[[nodiscard]] auto getBGColor() const -> Uint8 { return bg_color_; } // Devuelve el color de la habitación [[nodiscard]] auto getBGColor() const -> Uint8 { return bg_color_; }
[[nodiscard]] auto getBorderColor() const -> Uint8 { return border_color_; } // Devuelve el color del borde [[nodiscard]] auto getBorderColor() const -> Uint8 { return border_color_; }
void renderMap(); // Dibuja el mapa en pantalla void renderMap();
void renderEnemies(); // Dibuja los enemigos en pantalla void renderEnemies();
void renderItems(); // Dibuja los objetos en pantalla void renderItems();
#ifdef _DEBUG #ifdef _DEBUG
void redrawMap(); // Redibuja el mapa (para actualizar modo debug) void redrawMap();
void updateEditorMode(float delta_time); // Actualiza animaciones sin mover enemigos (para editor) void updateEditorMode(float delta_time);
void resetEnemyPositions(const std::vector<Enemy::Data>& enemy_data); // Resetea enemigos a posiciones iniciales void resetEnemyPositions(const std::vector<Enemy::Data>& enemy_data);
auto getEnemyManager() -> EnemyManager* { return enemy_manager_.get(); } // Acceso al gestor de enemigos (para editor) auto getEnemyManager() -> EnemyManager* { return enemy_manager_.get(); }
auto getItemManager() -> ItemManager* { return item_manager_.get(); } // Acceso al gestor de items (para editor) auto getItemManager() -> ItemManager* { return item_manager_.get(); }
void setBgColor(Uint8 color); // Cambia color de fondo y redibuja (para editor) void setBgColor(Uint8 color);
void setItemColors(Uint8 color1, Uint8 color2); // Cambia colores de items (para editor) void setItemColors(Uint8 color1, Uint8 color2);
void setTile(int index, int tile_value); // Cambia un tile y redibuja (para editor) void setTile(int index, int tile_value);
[[nodiscard]] auto getTileSetFile() const -> const std::string& { return tile_set_file_; } [[nodiscard]] auto getTileSetFile() const -> const std::string& { return tile_set_file_; }
[[nodiscard]] auto getTileSetWidth() const -> int { return tile_set_width_; } [[nodiscard]] auto getTileSetWidth() const -> int { return tile_set_width_; }
#endif #endif
void update(float delta_time); // Actualiza las variables y objetos de la habitación void update(float delta_time);
auto getRoom(Border border) -> std::string; // Devuelve la cadena del fichero de la habitación contigua segun el borde auto getRoom(Border border) -> std::string;
auto getTile(SDL_FPoint point) -> Tile; // Devuelve el tipo de tile que hay en ese pixel auto enemyCollision(SDL_FRect& rect) -> bool;
auto getTile(int index) -> Tile; // Devuelve el tipo de tile en un índice del tilemap auto itemCollision(SDL_FRect& rect) -> bool;
auto enemyCollision(SDL_FRect& rect) -> bool; // Indica si hay colision con un enemigo a partir de un rectangulo void setPaused(bool value);
auto itemCollision(SDL_FRect& rect) -> bool; // Indica si hay colision con un objeto a partir de un rectangulo [[nodiscard]] auto getConveyorBeltDirection() const -> int { return conveyor_belt_direction_; }
static auto getTileSize() -> int { return TILE_SIZE; } // Obten el tamaño del tile
static auto getSlopeHeight(SDL_FPoint p, Tile slope) -> int; // Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile
auto checkRightSurfaces(const SDL_FRect& rect) -> int; // Comprueba las colisiones
auto checkLeftSurfaces(const SDL_FRect& rect) -> int; // Comprueba las colisiones
auto checkTopSurfaces(const SDL_FRect& rect) -> int; // Comprueba las colisiones
auto checkBottomSurfaces(const SDL_FRect& rect) -> int; // Comprueba las colisiones
auto checkAutoSurfaces(const SDL_FRect& rect) -> int; // Comprueba las colisiones
auto checkTopSurfaces(const SDL_FPoint& p) -> bool; // Comprueba las colisiones
auto checkConveyorBelts(const SDL_FPoint& p) -> bool; // Comprueba las colisiones
auto checkLeftSlopes(const LineVertical& line) -> int; // Comprueba las colisiones
auto checkLeftSlopes(const SDL_FPoint& p) -> bool; // Comprueba las colisiones
auto checkRightSlopes(const LineVertical& line) -> int; // Comprueba las colisiones
auto checkRightSlopes(const SDL_FPoint& p) -> bool; // Comprueba las colisiones
[[nodiscard]] auto getSlopeAtPoint(const SDL_FPoint& p) const -> const LineDiagonal*; // Obtiene puntero a slope en un punto
void setPaused(bool value); // Pone el mapa en modo pausa
[[nodiscard]] auto getConveyorBeltDirection() const -> int { return conveyor_belt_direction_; } // Obten la direccion de las superficies automaticas
[[nodiscard]] auto getTileCollider() const -> const TileCollider&; [[nodiscard]] auto getTileCollider() const -> const TileCollider&;
// Método de carga de archivos YAML (delegado a RoomLoader) // Método de carga de archivos YAML (delegado a RoomLoader)
static auto loadYAML(const std::string& file_path, bool verbose = false) -> Data; // Carga habitación desde archivo YAML unificado static auto loadYAML(const std::string& file_path, bool verbose = false) -> Data;
private: private:
// Constantes static constexpr int TILE_SIZE = ::Tile::SIZE;
static constexpr int TILE_SIZE = ::Tile::SIZE; // Ancho del tile en pixels static constexpr int MAP_WIDTH = ::Map::WIDTH;
static constexpr int MAP_WIDTH = ::Map::WIDTH; // Ancho del mapa en tiles static constexpr int MAP_HEIGHT = ::Map::HEIGHT;
static constexpr int MAP_HEIGHT = ::Map::HEIGHT; // Alto del mapa en tiles
// Objetos y punteros std::unique_ptr<EnemyManager> enemy_manager_;
std::unique_ptr<EnemyManager> enemy_manager_; // Gestor de enemigos de la habitación std::unique_ptr<ItemManager> item_manager_;
std::unique_ptr<ItemManager> item_manager_; // Gestor de items de la habitación std::unique_ptr<CollisionMap> collision_map_;
std::unique_ptr<CollisionMap> collision_map_; // Mapa de colisiones de la habitación std::unique_ptr<TilemapRenderer> tilemap_renderer_;
std::unique_ptr<TilemapRenderer> tilemap_renderer_; // Renderizador del mapa de tiles std::shared_ptr<Surface> surface_;
std::shared_ptr<Surface> surface_; // Textura con los graficos de la habitación std::shared_ptr<Scoreboard::Data> data_;
std::shared_ptr<Scoreboard::Data> data_; // Puntero a los datos del marcador
// --- Variables --- std::string number_;
std::string number_; // Numero de la habitación Uint8 bg_color_{0};
Uint8 bg_color_{0}; // Color de fondo de la habitación Uint8 border_color_{0};
Uint8 border_color_{0}; // Color del borde de la pantalla Uint8 item_color1_{12};
Uint8 item_color1_{12}; // Color 1 para los items de la habitación Uint8 item_color2_{6};
Uint8 item_color2_{6}; // Color 2 para los items de la habitación std::string upper_room_;
std::string upper_room_; // Identificador de la habitación que se encuentra arriba std::string lower_room_;
std::string lower_room_; // Identificador de la habitación que se encuentra abajp std::string left_room_;
std::string left_room_; // Identificador de la habitación que se encuentra a la izquierda std::string right_room_;
std::string right_room_; // Identificador de la habitación que se encuentra a la derecha std::string tile_set_file_;
std::string tile_set_file_; // Imagen con los graficos para la habitación std::vector<int> tile_map_;
std::vector<int> tile_map_; // Indice de los tiles a dibujar en la habitación (embebido desde YAML) int conveyor_belt_direction_{0};
int conveyor_belt_direction_{0}; // Sentido en el que arrastran las superficies automáticas de la habitación bool is_paused_{false};
bool is_paused_{false}; // Indica si el mapa esta en modo pausa int tile_set_width_{0};
int tile_set_width_{0}; // Ancho del tileset en tiles
// --- Funciones --- void initializeRoom(const Data& room);
void initializeRoom(const Data& room); // Inicializa los valores };
};

View File

@@ -4,48 +4,34 @@
#include "core/rendering/sprite/sprite.hpp" #include "core/rendering/sprite/sprite.hpp"
#include "core/rendering/surface.hpp" #include "core/rendering/surface.hpp"
#ifdef _DEBUG #ifdef _DEBUG
#include "core/resources/resource_cache.hpp" // Para Resource::Cache (collision.gif)
#include "core/system/debug.hpp" #include "core/system/debug.hpp"
#endif #endif
#include "game/gameplay/collision_map.hpp"
#include "utils/utils.hpp"
// Constructor
TilemapRenderer::TilemapRenderer(std::vector<int> tile_map, int tile_set_width, std::shared_ptr<Surface> tileset_surface, Uint8 bg_color, int conveyor_belt_direction) TilemapRenderer::TilemapRenderer(std::vector<int> tile_map, int tile_set_width, std::shared_ptr<Surface> tileset_surface, Uint8 bg_color, int conveyor_belt_direction)
: tile_map_(std::move(tile_map)), : tile_map_(std::move(tile_map)),
tile_set_width_(tile_set_width), tile_set_width_(tile_set_width),
tileset_surface_(std::move(tileset_surface)), tileset_surface_(std::move(tileset_surface)),
bg_color_(bg_color), bg_color_(bg_color),
conveyor_belt_direction_(conveyor_belt_direction) { conveyor_belt_direction_(conveyor_belt_direction) {
// Crear la surface del mapa
map_surface_ = std::make_shared<Surface>(PlayArea::WIDTH, PlayArea::HEIGHT); map_surface_ = std::make_shared<Surface>(PlayArea::WIDTH, PlayArea::HEIGHT);
} }
// Inicializa el renderizador void TilemapRenderer::initialize(const std::vector<int>& collision_tile_map) {
void TilemapRenderer::initialize(const CollisionMap* collision_map) { setAnimatedTiles(collision_tile_map);
setAnimatedTiles(collision_map); fillMapTexture(collision_tile_map);
fillMapTexture(collision_map);
} }
// Actualiza las animaciones de tiles
void TilemapRenderer::update(float delta_time) { void TilemapRenderer::update(float delta_time) {
if (is_paused_) { if (is_paused_) { return; }
return;
}
// Actualiza el acumulador de tiempo
time_accumulator_ += delta_time; time_accumulator_ += delta_time;
// Actualiza los tiles animados
updateAnimatedTiles(); updateAnimatedTiles();
} }
// Renderiza el mapa completo en pantalla
void TilemapRenderer::render() { void TilemapRenderer::render() {
// Dibuja la textura con el mapa en pantalla
SDL_FRect dest = {.x = 0, .y = 0, .w = PlayArea::WIDTH, .h = PlayArea::HEIGHT}; SDL_FRect dest = {.x = 0, .y = 0, .w = PlayArea::WIDTH, .h = PlayArea::HEIGHT};
map_surface_->render(nullptr, &dest); map_surface_->render(nullptr, &dest);
// Dibuja los tiles animados
#ifdef _DEBUG #ifdef _DEBUG
if (!Debug::get()->isEnabled()) { if (!Debug::get()->isEnabled()) {
renderAnimatedTiles(); renderAnimatedTiles();
@@ -56,52 +42,11 @@ void TilemapRenderer::render() {
} }
#ifdef _DEBUG #ifdef _DEBUG
// Renderiza las superficies de colisión en modo debug (función helper estática) // Redibuja el tilemap (para actualizar modo debug: pinta collision tilemap o tiles normales)
static void renderDebugCollisionSurfaces(const CollisionMap* collision_map) { void TilemapRenderer::redrawMap(const std::vector<int>& collision_tile_map) {
auto surface = Screen::get()->getRendererSurface(); fillMapTexture(collision_tile_map);
// BottomSurfaces
for (auto l : collision_map->getBottomFloors()) {
surface->drawLine(l.x1, l.y, l.x2, l.y, 2);
}
// TopSurfaces
for (auto l : collision_map->getTopFloors()) {
surface->drawLine(l.x1, l.y, l.x2, l.y, 4);
}
// LeftSurfaces
for (auto l : collision_map->getLeftWalls()) {
surface->drawLine(l.x, l.y1, l.x, l.y2, 8);
}
// RightSurfaces
for (auto l : collision_map->getRightWalls()) {
surface->drawLine(l.x, l.y1, l.x, l.y2, 6);
}
// LeftSlopes
for (auto l : collision_map->getLeftSlopes()) {
surface->drawLine(l.x1, l.y1, l.x2, l.y2, 10);
}
// RightSlopes
for (auto l : collision_map->getRightSlopes()) {
surface->drawLine(l.x1, l.y1, l.x2, l.y2, 12);
}
// AutoSurfaces (Conveyor Belts)
for (auto l : collision_map->getConveyorBeltFloors()) {
surface->drawLine(l.x1, l.y, l.x2, l.y, 14);
}
} }
// Redibuja el tilemap (para actualizar modo debug)
void TilemapRenderer::redrawMap(const CollisionMap* collision_map) {
fillMapTexture(collision_map);
}
// Cambia un tile y repinta solo esa celda en la map_surface
void TilemapRenderer::setTile(int index, int tile_value) { void TilemapRenderer::setTile(int index, int tile_value) {
if (index < 0 || index >= static_cast<int>(tile_map_.size())) { return; } if (index < 0 || index >= static_cast<int>(tile_map_.size())) { return; }
@@ -113,11 +58,9 @@ void TilemapRenderer::setTile(int index, int tile_value) {
auto previous_renderer = Screen::get()->getRendererSurface(); auto previous_renderer = Screen::get()->getRendererSurface();
Screen::get()->setRendererSurface(map_surface_); Screen::get()->setRendererSurface(map_surface_);
// Borrar la celda con el color de fondo
SDL_FRect cell = {.x = static_cast<float>(col * TILE_SIZE), .y = static_cast<float>(row * TILE_SIZE), .w = static_cast<float>(TILE_SIZE), .h = static_cast<float>(TILE_SIZE)}; SDL_FRect cell = {.x = static_cast<float>(col * TILE_SIZE), .y = static_cast<float>(row * TILE_SIZE), .w = static_cast<float>(TILE_SIZE), .h = static_cast<float>(TILE_SIZE)};
map_surface_->fillRect(&cell, bg_color_); map_surface_->fillRect(&cell, bg_color_);
// Dibujar el nuevo tile (si no es vacío ni animado)
if (tile_value > -1) { if (tile_value > -1) {
const bool IS_ANIMATED = (tile_value >= 18 * tile_set_width_) && (tile_value < 19 * tile_set_width_); const bool IS_ANIMATED = (tile_value >= 18 * tile_set_width_) && (tile_value < 19 * tile_set_width_);
if (!IS_ANIMATED) { if (!IS_ANIMATED) {
@@ -131,27 +74,44 @@ void TilemapRenderer::setTile(int index, int tile_value) {
Screen::get()->setRendererSurface(previous_renderer); Screen::get()->setRendererSurface(previous_renderer);
} }
// Renderiza el collision tilemap superpuesto (modo debug)
static void renderDebugCollisionTilemap(const std::vector<int>& collision_tile_map) {
auto collision_surface = Resource::Cache::get()->getSurface("collision.gif");
if (!collision_surface) { return; }
for (int y = 0; y < Map::HEIGHT; ++y) {
for (int x = 0; x < Map::WIDTH; ++x) {
int index = (y * Map::WIDTH) + x;
if (index >= static_cast<int>(collision_tile_map.size())) { continue; }
int tile = collision_tile_map[index];
if (tile <= 0) { continue; }
SDL_FRect clip = {
.x = static_cast<float>(tile * Tile::SIZE),
.y = 0,
.w = static_cast<float>(Tile::SIZE),
.h = static_cast<float>(Tile::SIZE)};
collision_surface->render(x * Tile::SIZE, y * Tile::SIZE, &clip);
}
}
}
#endif #endif
// Pinta el mapa estático y debug lines // Pinta el mapa estático
void TilemapRenderer::fillMapTexture(const CollisionMap* collision_map) { // NOLINT(readability-convert-member-functions-to-static) void TilemapRenderer::fillMapTexture(const std::vector<int>& collision_tile_map) {
auto previous_renderer = Screen::get()->getRendererSurface(); auto previous_renderer = Screen::get()->getRendererSurface();
Screen::get()->setRendererSurface(map_surface_); Screen::get()->setRendererSurface(map_surface_);
map_surface_->clear(bg_color_); map_surface_->clear(bg_color_);
// Los tileSetFiles son de 20x20 tiles. El primer tile es el 0. Cuentan hacia la derecha y hacia abajo
SDL_FRect clip = {.x = 0, .y = 0, .w = TILE_SIZE, .h = TILE_SIZE}; SDL_FRect clip = {.x = 0, .y = 0, .w = TILE_SIZE, .h = TILE_SIZE};
for (int y = 0; y < MAP_HEIGHT; ++y) { for (int y = 0; y < MAP_HEIGHT; ++y) {
for (int x = 0; x < MAP_WIDTH; ++x) { for (int x = 0; x < MAP_WIDTH; ++x) {
// Tiled pone los tiles vacios del mapa como cero y empieza a contar de 1 a n.
// Al cargar el mapa en memoria, se resta uno, por tanto los tiles vacios son -1
// Tampoco hay que dibujar los tiles animados que estan en la fila 19 (indices)
const int INDEX = (y * MAP_WIDTH) + x; const int INDEX = (y * MAP_WIDTH) + x;
const bool A = (tile_map_[INDEX] >= 18 * tile_set_width_) && (tile_map_[INDEX] < 19 * tile_set_width_); // Los tiles animados (fila 18 del tileset) no se pintan en la textura estática
const bool B = tile_map_[INDEX] > -1; const bool IS_ANIMATED = (tile_map_[INDEX] >= 18 * tile_set_width_) && (tile_map_[INDEX] < 19 * tile_set_width_);
const bool HAS_TILE = tile_map_[INDEX] > -1;
if (B && !A) { if (HAS_TILE && !IS_ANIMATED) {
clip.x = (tile_map_[INDEX] % tile_set_width_) * TILE_SIZE; clip.x = (tile_map_[INDEX] % tile_set_width_) * TILE_SIZE;
clip.y = (tile_map_[INDEX] / tile_set_width_) * TILE_SIZE; clip.y = (tile_map_[INDEX] / tile_set_width_) * TILE_SIZE;
#ifdef _DEBUG #ifdef _DEBUG
@@ -166,25 +126,21 @@ void TilemapRenderer::fillMapTexture(const CollisionMap* collision_map) { // NO
} }
#ifdef _DEBUG #ifdef _DEBUG
// Pinta las superficies en el modo debug // En modo debug, pintar el collision tilemap en vez de las líneas de colisión antiguas
if (Debug::get()->isEnabled()) { if (Debug::get()->isEnabled()) {
renderDebugCollisionSurfaces(collision_map); renderDebugCollisionTilemap(collision_tile_map);
} }
#endif // _DEBUG #endif
Screen::get()->setRendererSurface(previous_renderer); Screen::get()->setRendererSurface(previous_renderer);
} }
// Localiza todos los tiles animados // Localiza tiles animados (conveyor belts) usando el collision_tile_map
void TilemapRenderer::setAnimatedTiles(const CollisionMap* collision_map) { // NOLINT(readability-convert-member-functions-to-static) void TilemapRenderer::setAnimatedTiles(const std::vector<int>& collision_tile_map) {
// Recorre la habitación entera por filas buscando tiles de tipo t_animated for (int i = 0; i < static_cast<int>(tile_map_.size()); ++i) {
for (int i = 0; i < (int)tile_map_.size(); ++i) { // Un tile es animado si su valor en el collision tilemap es COLLISION_ANIMATED (6)
const auto TILE_TYPE = collision_map->getTile(i); if (i < static_cast<int>(collision_tile_map.size()) && collision_tile_map[i] == COLLISION_ANIMATED) {
if (TILE_TYPE == CollisionMap::Tile::ANIMATED) {
// La i es la ubicación
const int X = (i % MAP_WIDTH) * TILE_SIZE; const int X = (i % MAP_WIDTH) * TILE_SIZE;
const int Y = (i / MAP_WIDTH) * TILE_SIZE; const int Y = (i / MAP_WIDTH) * TILE_SIZE;
// TileMap[i] es el tile a poner
const int XC = (tile_map_[i] % tile_set_width_) * TILE_SIZE; const int XC = (tile_map_[i] % tile_set_width_) * TILE_SIZE;
const int YC = (tile_map_[i] / tile_set_width_) * TILE_SIZE; const int YC = (tile_map_[i] / tile_set_width_) * TILE_SIZE;
@@ -197,14 +153,10 @@ void TilemapRenderer::setAnimatedTiles(const CollisionMap* collision_map) { //
} }
} }
// Actualiza tiles animados void TilemapRenderer::updateAnimatedTiles() {
void TilemapRenderer::updateAnimatedTiles() { // NOLINT(readability-make-member-function-const)
const int NUM_FRAMES = 4; const int NUM_FRAMES = 4;
// Calcular frame actual basado en tiempo
const int CURRENT_FRAME = static_cast<int>(time_accumulator_ / CONVEYOR_FRAME_DURATION) % NUM_FRAMES; const int CURRENT_FRAME = static_cast<int>(time_accumulator_ / CONVEYOR_FRAME_DURATION) % NUM_FRAMES;
// Calcular offset basado en dirección
int offset = 0; int offset = 0;
if (conveyor_belt_direction_ == -1) { if (conveyor_belt_direction_ == -1) {
offset = CURRENT_FRAME * TILE_SIZE; offset = CURRENT_FRAME * TILE_SIZE;
@@ -219,7 +171,6 @@ void TilemapRenderer::updateAnimatedTiles() { // NOLINT(readability-make-member
} }
} }
// Renderiza tiles animados
void TilemapRenderer::renderAnimatedTiles() { void TilemapRenderer::renderAnimatedTiles() {
for (const auto& a : animated_tiles_) { for (const auto& a : animated_tiles_) {
a.sprite->render(); a.sprite->render();

View File

@@ -3,118 +3,63 @@
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <memory> // Para shared_ptr #include <memory> // Para shared_ptr
#include <string> // Para string
#include <vector> // Para vector #include <vector> // Para vector
#include "utils/defines.hpp" #include "utils/defines.hpp"
class Surface; class Surface;
class Sprite; class Sprite;
class CollisionMap;
/**
* @brief Renderizador de tilemap de una habitación
*
* Responsabilidades:
* - Renderizar el mapa de tiles estático
* - Gestionar tiles animados (conveyor belts)
* - Actualizar animaciones basadas en tiempo
* - Renderizar debug visualization (en modo DEBUG)
*/
class TilemapRenderer { class TilemapRenderer {
public: public:
/**
* @brief Constructor
* @param tile_map Vector con índices de tiles de la habitación
* @param tile_set_width Ancho del tileset en tiles
* @param tileset_surface Surface con los gráficos del tileset
* @param bg_color Color de fondo de la habitación (como string)
* @param conveyor_belt_direction Dirección de las cintas transportadoras (-1, 0, +1)
*/
TilemapRenderer(std::vector<int> tile_map, int tile_set_width, std::shared_ptr<Surface> tileset_surface, Uint8 bg_color, int conveyor_belt_direction); TilemapRenderer(std::vector<int> tile_map, int tile_set_width, std::shared_ptr<Surface> tileset_surface, Uint8 bg_color, int conveyor_belt_direction);
~TilemapRenderer() = default; ~TilemapRenderer() = default;
// Prohibir copia y movimiento
TilemapRenderer(const TilemapRenderer&) = delete; TilemapRenderer(const TilemapRenderer&) = delete;
auto operator=(const TilemapRenderer&) -> TilemapRenderer& = delete; auto operator=(const TilemapRenderer&) -> TilemapRenderer& = delete;
TilemapRenderer(TilemapRenderer&&) = delete; TilemapRenderer(TilemapRenderer&&) = delete;
auto operator=(TilemapRenderer&&) -> TilemapRenderer& = delete; auto operator=(TilemapRenderer&&) -> TilemapRenderer& = delete;
/** void initialize(const std::vector<int>& collision_tile_map);
* @brief Inicializa el renderizador
* @param collision_map Mapa de colisiones para determinar tiles animados
*
* Crea la textura del mapa, pinta los tiles estáticos, y localiza tiles animados
*/
void initialize(const CollisionMap* collision_map);
/**
* @brief Actualiza las animaciones de tiles
* @param delta_time Tiempo transcurrido desde el último frame (segundos)
*/
void update(float delta_time); void update(float delta_time);
/**
* @brief Renderiza el mapa completo en pantalla
*
* Dibuja la textura del mapa y los tiles animados
*/
void render(); void render();
#ifdef _DEBUG #ifdef _DEBUG
/** void redrawMap(const std::vector<int>& collision_tile_map);
* @brief Redibuja el tilemap (para actualizar modo debug)
* @param collision_map Mapa de colisiones para dibujar líneas de debug
*
* Llamado cuando se activa/desactiva el modo debug para actualizar la visualización
*/
void redrawMap(const CollisionMap* collision_map);
void setBgColor(Uint8 color) { bg_color_ = color; } void setBgColor(Uint8 color) { bg_color_ = color; }
void setTile(int index, int tile_value); // Cambia un tile y repinta esa celda void setTile(int index, int tile_value);
#endif #endif
/**
* @brief Activa/desactiva modo pausa
* @param paused true para pausar, false para reanudar
*
* Nota: Actualmente no afecta al renderizado, pero mantiene consistencia con Room
*/
void setPaused(bool paused) { is_paused_ = paused; } void setPaused(bool paused) { is_paused_ = paused; }
// Getter para la surface del mapa (usado por Room para acceso directo si es necesario)
[[nodiscard]] auto getMapSurface() const -> std::shared_ptr<Surface> { return map_surface_; } [[nodiscard]] auto getMapSurface() const -> std::shared_ptr<Surface> { return map_surface_; }
private: private:
// Estructura para tiles animados (conveyor belts)
struct AnimatedTile { struct AnimatedTile {
std::shared_ptr<Sprite> sprite{nullptr}; // SurfaceSprite para dibujar el tile std::shared_ptr<Sprite> sprite{nullptr};
int x_orig{0}; // Posición X del primer tile de la animación en tilesheet int x_orig{0};
}; };
// === Constantes === static constexpr int TILE_SIZE = Tile::SIZE;
static constexpr int TILE_SIZE = Tile::SIZE; // Ancho del tile en pixels static constexpr int MAP_WIDTH = Map::WIDTH;
static constexpr int MAP_WIDTH = Map::WIDTH; // Ancho del mapa en tiles static constexpr int MAP_HEIGHT = Map::HEIGHT;
static constexpr int MAP_HEIGHT = Map::HEIGHT; // Alto del mapa en tiles static constexpr int PLAY_AREA_WIDTH = PlayArea::WIDTH;
static constexpr int PLAY_AREA_WIDTH = PlayArea::WIDTH; // Ancho del área de juego en pixels static constexpr int PLAY_AREA_HEIGHT = PlayArea::HEIGHT;
static constexpr int PLAY_AREA_HEIGHT = PlayArea::HEIGHT; // Alto del área de juego en pixels static constexpr float CONVEYOR_FRAME_DURATION = 0.05F;
static constexpr float CONVEYOR_FRAME_DURATION = 0.05F; // Duración de cada frame (3 frames @ 60fps) static constexpr int COLLISION_ANIMATED = 6; // Valor del tile de conveyor en el collision tilemap
// === Datos de la habitación === std::vector<int> tile_map_;
std::vector<int> tile_map_; // Índices de tiles de la habitación int tile_set_width_;
int tile_set_width_; // Ancho del tileset en tiles std::shared_ptr<Surface> tileset_surface_;
std::shared_ptr<Surface> tileset_surface_; // Gráficos del tileset Uint8 bg_color_{0};
Uint8 bg_color_{0}; // Color de fondo int conveyor_belt_direction_;
int conveyor_belt_direction_; // Dirección de conveyor belts
// === Renderizado === std::shared_ptr<Surface> map_surface_;
std::shared_ptr<Surface> map_surface_; // Textura para el mapa de la habitación std::vector<AnimatedTile> animated_tiles_;
std::vector<AnimatedTile> animated_tiles_; // Tiles animados (conveyor belts) float time_accumulator_{0.0F};
float time_accumulator_{0.0F}; // Acumulador de tiempo para animaciones bool is_paused_{false};
bool is_paused_{false}; // Indica si está en modo pausa
// === Métodos privados === void fillMapTexture(const std::vector<int>& collision_tile_map);
void fillMapTexture(const CollisionMap* collision_map); // Pinta el mapa estático y debug lines void setAnimatedTiles(const std::vector<int>& collision_tile_map);
void setAnimatedTiles(const CollisionMap* collision_map); // Localiza todos los tiles animados void updateAnimatedTiles();
void updateAnimatedTiles(); // Actualiza tiles animados void renderAnimatedTiles();
void renderAnimatedTiles(); // Renderiza tiles animados
}; };

View File

@@ -132,156 +132,6 @@ auto checkCollision(const SDL_FPoint& point, const SDL_FRect& rect) -> bool {
return true; return true;
} }
// Detector de colisiones entre una linea horizontal y un rectangulo
auto checkCollision(const LineHorizontal& l, const SDL_FRect& rect) -> bool {
SDL_Rect r = toSDLRect(rect);
// Comprueba si la linea esta por encima del rectangulo
if (l.y < r.y) {
return false;
}
// Comprueba si la linea esta por debajo del rectangulo
if (l.y >= r.y + r.h) {
return false;
}
// Comprueba si el inicio de la linea esta a la derecha del rectangulo
if (l.x1 >= r.x + r.w) {
return false;
}
// Comprueba si el final de la linea esta a la izquierda del rectangulo
if (l.x2 < r.x) {
return false;
}
// Si ha llegado hasta aquí, hay colisión
return true;
}
// Detector de colisiones entre una linea vertical y un rectangulo
auto checkCollision(const LineVertical& l, const SDL_FRect& rect) -> bool {
SDL_Rect r = toSDLRect(rect);
// Comprueba si la linea esta por la izquierda del rectangulo
if (l.x < r.x) {
return false;
}
// Comprueba si la linea esta por la derecha del rectangulo
if (l.x >= r.x + r.w) {
return false;
}
// Comprueba si el inicio de la linea esta debajo del rectangulo
if (l.y1 >= r.y + r.h) {
return false;
}
// Comprueba si el final de la linea esta encima del rectangulo
if (l.y2 < r.y) {
return false;
}
// Si ha llegado hasta aquí, hay colisión
return true;
}
// Detector de colisiones entre una linea horizontal y un punto
auto checkCollision(const LineHorizontal& l, const SDL_FPoint& point) -> bool {
SDL_Point p = toSDLPoint(point);
// Comprueba si el punto esta sobre la linea
if (p.y > l.y) {
return false;
}
// Comprueba si el punto esta bajo la linea
if (p.y < l.y) {
return false;
}
// Comprueba si el punto esta a la izquierda de la linea
if (p.x < l.x1) {
return false;
}
// Comprueba si el punto esta a la derecha de la linea
if (p.x > l.x2) {
return false;
}
// Si ha llegado aquí, hay colisión
return true;
}
// Detector de colisiones entre dos lineas
auto checkCollision(const Line& l1, const Line& l2) -> SDL_Point {
const float X1 = l1.x1;
const float Y1 = l1.y1;
const float X2 = l1.x2;
const float Y2 = l1.y2;
const float X3 = l2.x1;
const float Y3 = l2.y1;
const float X4 = l2.x2;
const float Y4 = l2.y2;
// calculate the direction of the lines
float u_a = (((X4 - X3) * (Y1 - Y3)) - ((Y4 - Y3) * (X1 - X3))) / (((Y4 - Y3) * (X2 - X1)) - ((X4 - X3) * (Y2 - Y1)));
float u_b = (((X2 - X1) * (Y1 - Y3)) - ((Y2 - Y1) * (X1 - X3))) / (((Y4 - Y3) * (X2 - X1)) - ((X4 - X3) * (Y2 - Y1)));
// if uA and uB are between 0-1, lines are colliding
if (u_a >= 0 && u_a <= 1 && u_b >= 0 && u_b <= 1) {
// Calcula la intersección
const float X = X1 + (u_a * (X2 - X1));
const float Y = Y1 + (u_a * (Y2 - Y1));
return {.x = static_cast<int>(std::round(X)), .y = static_cast<int>(std::round(Y))};
}
return {.x = -1, .y = -1};
}
// Detector de colisiones entre dos lineas
auto checkCollision(const LineDiagonal& l1, const LineVertical& l2) -> SDL_Point {
const float X1 = l1.x1;
const float Y1 = l1.y1;
const float X2 = l1.x2;
const float Y2 = l1.y2;
const float X3 = l2.x;
const float Y3 = l2.y1;
const float X4 = l2.x;
const float Y4 = l2.y2;
// calculate the direction of the lines
float u_a = (((X4 - X3) * (Y1 - Y3)) - ((Y4 - Y3) * (X1 - X3))) / (((Y4 - Y3) * (X2 - X1)) - ((X4 - X3) * (Y2 - Y1)));
float u_b = (((X2 - X1) * (Y1 - Y3)) - ((Y2 - Y1) * (X1 - X3))) / (((Y4 - Y3) * (X2 - X1)) - ((X4 - X3) * (Y2 - Y1)));
// if uA and uB are between 0-1, lines are colliding
if (u_a >= 0 && u_a <= 1 && u_b >= 0 && u_b <= 1) {
// Calcula la intersección
const float X = X1 + (u_a * (X2 - X1));
const float Y = Y1 + (u_a * (Y2 - Y1));
return {.x = static_cast<int>(std::round(X)), .y = static_cast<int>(std::round(Y))};
}
return {.x = -1, .y = -1};
}
// Normaliza una linea diagonal
void normalizeLine(LineDiagonal& l) {
// Las lineas diagonales van de izquierda a derecha
// x2 mayor que x1
if (l.x2 < l.x1) {
const int X = l.x1;
const int Y = l.y1;
l.x1 = l.x2;
l.y1 = l.y2;
l.x2 = X;
l.y2 = Y;
}
}
// Convierte SDL_FRect a SDL_Rect // Convierte SDL_FRect a SDL_Rect
auto toSDLRect(const SDL_FRect& frect) -> SDL_Rect { auto toSDLRect(const SDL_FRect& frect) -> SDL_Rect {
SDL_Rect rect = { SDL_Rect rect = {
@@ -300,39 +150,6 @@ auto toSDLPoint(const SDL_FPoint& fpoint) -> SDL_Point {
return point; return point;
} }
// Detector de colisiones entre un punto y una linea diagonal
auto checkCollision(const SDL_FPoint& point, const LineDiagonal& l) -> bool {
SDL_Point p = toSDLPoint(point);
// Comprueba si el punto está en alineado con la linea
if (abs(p.x - l.x1) != abs(p.y - l.y1)) {
return false;
}
// Comprueba si está a la derecha de la linea
if (p.x > l.x1 && p.x > l.x2) {
return false;
}
// Comprueba si está a la izquierda de la linea
if (p.x < l.x1 && p.x < l.x2) {
return false;
}
// Comprueba si está por encima de la linea
if (p.y > l.y1 && p.y > l.y2) {
return false;
}
// Comprueba si está por debajo de la linea
if (p.y < l.y1 && p.y < l.y2) {
return false;
}
// En caso contrario, el punto está en la linea
return true;
}
// Convierte una cadena a un entero de forma segura // Convierte una cadena a un entero de forma segura
auto safeStoi(const std::string& value, int default_value) -> int { auto safeStoi(const std::string& value, int default_value) -> int {
try { try {

View File

@@ -12,26 +12,6 @@ struct Circle {
int r{0}; int r{0};
}; };
// Estructura para definir una linea horizontal
struct LineHorizontal {
int x1{0}, x2{0}, y{0};
};
// Estructura para definir una linea vertical
struct LineVertical {
int x{0}, y1{0}, y2{0};
};
// Estructura para definir una linea diagonal
struct LineDiagonal {
int x1{0}, y1{0}, x2{0}, y2{0};
};
// Estructura para definir una linea
struct Line {
int x1{0}, y1{0}, x2{0}, y2{0};
};
// Estructura para definir un color RGB // Estructura para definir un color RGB
struct Rgb { struct Rgb {
Uint8 r{0}; Uint8 r{0};
@@ -51,14 +31,6 @@ auto checkCollision(const Circle& a, const Circle& b) -> bool;
auto checkCollision(const Circle& a, const SDL_FRect& rect) -> bool; // Colisión círculo-rectángulo auto checkCollision(const Circle& a, const SDL_FRect& rect) -> bool; // Colisión círculo-rectángulo
auto checkCollision(const SDL_FRect& a, const SDL_FRect& b) -> bool; // Colisión rectángulo-rectángulo auto checkCollision(const SDL_FRect& a, const SDL_FRect& b) -> bool; // Colisión rectángulo-rectángulo
auto checkCollision(const SDL_FPoint& p, const SDL_FRect& r) -> bool; // Colisión punto-rectángulo auto checkCollision(const SDL_FPoint& p, const SDL_FRect& r) -> bool; // Colisión punto-rectángulo
auto checkCollision(const LineHorizontal& l, const SDL_FRect& r) -> bool; // Colisión línea horizontal-rectángulo
auto checkCollision(const LineVertical& l, const SDL_FRect& r) -> bool; // Colisión línea vertical-rectángulo
auto checkCollision(const LineHorizontal& l, const SDL_FPoint& p) -> bool; // Colisión línea horizontal-punto
auto checkCollision(const Line& l1, const Line& l2) -> SDL_Point; // Colisión línea-línea (intersección)
auto checkCollision(const LineDiagonal& l1, const LineVertical& l2) -> SDL_Point; // Colisión diagonal-vertical
auto checkCollision(const SDL_FPoint& p, const LineDiagonal& l) -> bool; // Colisión punto-diagonal
void normalizeLine(LineDiagonal& l); // Normaliza línea diagonal (x1 < x2)
// CONVERSIONES DE TIPOS SDL // CONVERSIONES DE TIPOS SDL
auto toSDLRect(const SDL_FRect& frect) -> SDL_Rect; // Convierte SDL_FRect a SDL_Rect auto toSDLRect(const SDL_FRect& frect) -> SDL_Rect; // Convierte SDL_FRect a SDL_Rect
auto toSDLPoint(const SDL_FPoint& fpoint) -> SDL_Point; // Convierte SDL_FPoint a SDL_Point auto toSDLPoint(const SDL_FPoint& fpoint) -> SDL_Point; // Convierte SDL_FPoint a SDL_Point