eliminat sistema de colisió antic
This commit is contained in:
10
CLAUDE.md
10
CLAUDE.md
@@ -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`.
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
|
||||||
};
|
};
|
||||||
@@ -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();
|
||||||
|
|||||||
@@ -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
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user