eliminar entrades legacy del fitxer de mapa

This commit is contained in:
2026-04-10 18:51:14 +02:00
parent 8ebf7894f2
commit 6743562292
20 changed files with 133 additions and 318 deletions

View File

@@ -3,10 +3,9 @@
#include <algorithm> // Para std::ranges::fill
#include <utility> // Para std::move
CollisionMap::CollisionMap(std::vector<int> collision_tile_map, int conveyor_belt_direction)
CollisionMap::CollisionMap(std::vector<int> collision_tile_map)
: collision_tile_map_(std::move(collision_tile_map)),
extended_tile_map_(EW * EH, 0),
conveyor_belt_direction_(conveyor_belt_direction),
tile_collider_(extended_tile_map_, EW, EH, CollisionBorder::PX) {
buildExtendedCenter();
}

View File

@@ -28,7 +28,7 @@ class CollisionMap {
const std::vector<int>* bottom_right{nullptr};
};
CollisionMap(std::vector<int> collision_tile_map, int conveyor_belt_direction);
explicit CollisionMap(std::vector<int> collision_tile_map);
~CollisionMap() = default;
CollisionMap(const CollisionMap&) = delete;
@@ -40,17 +40,12 @@ class CollisionMap {
void updateBorders(const AdjacentData& adjacent);
[[nodiscard]] auto getTileCollider() const -> const TileCollider& { return tile_collider_; }
[[nodiscard]] auto getConveyorBeltDirection() const -> int { return conveyor_belt_direction_; }
[[nodiscard]] auto getCollisionTileMap() const -> const std::vector<int>& { return collision_tile_map_; }
// Modifica un tile del mapa de colisiones (original + extendido) en runtime.
// Lo usan: el editor de mapas (debug) y el DoorManager para mostrar/ocultar muros de puertas.
void setCollisionTile(int index, int value);
#ifdef _DEBUG
void setConveyorBeltDirection(int direction) { conveyor_belt_direction_ = direction; }
#endif
private:
static constexpr int B = CollisionBorder::TILES; // Tiles de borde
static constexpr int MW = Map::WIDTH; // Ancho original (32)
@@ -60,8 +55,7 @@ class CollisionMap {
std::vector<int> collision_tile_map_; // Original (32×21)
std::vector<int> extended_tile_map_; // Extendido (38×27) — referenciado por TileCollider
int conveyor_belt_direction_;
TileCollider tile_collider_; // Debe ir después de extended_tile_map_ (usa referencia)
TileCollider tile_collider_; // Debe ir después de extended_tile_map_ (usa referencia)
// Copia el centro (room actual) al mapa extendido. Los bordes quedan como EMPTY (0).
void buildExtendedCenter();

View File

@@ -33,18 +33,18 @@ Room::Room(const std::string& room_path, std::shared_ptr<Scoreboard::Data> data)
// Crea el mapa de colisiones desde el collision_tile_map (debe ir antes
// del DoorManager porque éste lo necesita para mutar tiles dinámicamente)
collision_map_ = std::make_unique<CollisionMap>(room->collision_tile_map, conveyor_belt_direction_);
collision_map_ = std::make_unique<CollisionMap>(room->collision_tile_map);
// Crea el manager de puertas (necesita el CollisionMap para sincronizar muros)
door_manager_ = std::make_unique<DoorManager>(room->number, collision_map_.get());
initializeRoom(*room);
// Crea el renderizador del tilemap (necesita tile_map_, tile_set_width_, surface_, bg_color_, conveyor_belt_direction_).
// Se inicializa con el collision tile map ya modificado por las puertas (que han marcado sus
// celdas como WALL en el collision_map_, pero el renderer solo lo usa para detectar superficies
// de dibujo, no para colisión, así que pasamos la versión actualizada del collision_map_).
tilemap_renderer_ = std::make_unique<TilemapRenderer>(tile_map_, tile_set_width_, surface_, bg_color_, conveyor_belt_direction_);
// Crea el renderizador del tilemap. Se inicializa con el collision tile map ya
// modificado por las puertas (que han marcado sus celdas como WALL en el
// collision_map_, pero el renderer solo lo usa para detectar superficies de
// dibujo, no para colisión).
tilemap_renderer_ = std::make_unique<TilemapRenderer>(tile_map_, tile_set_width_, surface_, bg_color_);
tilemap_renderer_->initialize(collision_map_->getCollisionTileMap());
}
@@ -55,8 +55,6 @@ void Room::initializeRoom(const Data& room) {
// Asignar valores a las variables miembro
number_ = room.number;
bg_color_ = room.bg_color;
item_color1_ = room.item_color1;
item_color2_ = room.item_color2;
upper_room_ = room.upper_room;
lower_room_ = room.lower_room;
left_room_ = room.left_room;
@@ -64,7 +62,6 @@ void Room::initializeRoom(const Data& room) {
zone_ = room.zone;
tile_set_file_ = room.tile_set_file;
music_ = room.music;
conveyor_belt_direction_ = room.conveyor_belt_direction;
tile_map_ = room.tile_map; // Tilemap viene embebido en el YAML
surface_ = Resource::Cache::get()->getSurface(room.tile_set_file);
tile_set_width_ = surface_->getWidth() / TILE_SIZE;
@@ -80,18 +77,12 @@ void Room::initializeRoom(const Data& room) {
platform_manager_->addPlatform(std::make_shared<MovingPlatform>(plat_data));
}
// Crear los items usando el manager
// Crear los items usando el manager. Cada item lleva sus propios colores
// (con defaults si el yaml no los especificó); ya no hay color por habitación.
for (const auto& item : room.items) {
const SDL_FPoint ITEM_POS = {item.x, item.y};
if (!ItemTracker::get()->hasBeenPicked(room.number, ITEM_POS)) {
// Crear una copia local de los datos del item
Item::Data item_copy = item;
item_copy.color1 = item_color1_;
item_copy.color2 = item_color2_;
// Crear el objeto Item usando la copia modificada
item_manager_->addItem(std::make_shared<Item>(item_copy));
item_manager_->addItem(std::make_shared<Item>(item));
}
}
@@ -170,16 +161,6 @@ void Room::setTile(int index, int tile_value) {
}
}
// Cambia colores de items en vivo (para editor)
void Room::setItemColors(Uint8 color1, Uint8 color2) {
item_color1_ = color1;
item_color2_ = color2;
auto* item_mgr = item_manager_.get();
for (int i = 0; i < item_mgr->getCount(); ++i) {
item_mgr->getItem(i)->setColors(color1, color2);
}
}
// Cambia un collision tile en vivo (para editor)
void Room::setCollisionTile(int index, int value) {
collision_map_->setCollisionTile(index, value);
@@ -214,16 +195,9 @@ void Room::setTileSet(const std::string& tile_set_file) {
tile_map_,
tile_set_width_,
surface_,
bg_color_,
conveyor_belt_direction_);
bg_color_);
tilemap_renderer_->initialize(collision_map_->getCollisionTileMap());
}
// Cambia la dirección del conveyor belt en vivo (para editor)
void Room::setConveyorBeltDirection(int direction) {
conveyor_belt_direction_ = direction;
collision_map_->setConveyorBeltDirection(direction);
}
#endif
// Actualiza las variables y objetos de la habitación

View File

@@ -38,8 +38,6 @@ class Room {
struct Data {
std::string number;
Uint8 bg_color{0};
Uint8 item_color1{Defaults::Game::Room::ITEM_COLOR1};
Uint8 item_color2{Defaults::Game::Room::ITEM_COLOR2};
std::string upper_room;
std::string lower_room;
std::string left_room;
@@ -49,7 +47,6 @@ class Room {
std::string music; // Resuelto: zona o override del yaml
bool tile_set_overridden{false}; // True si el yaml tenía tileSetFile explícito
bool music_overridden{false}; // True si el yaml tenía music explícito
int conveyor_belt_direction{0};
std::vector<int> tile_map;
std::vector<int> collision_tile_map;
std::vector<Enemy::Data> enemies;
@@ -84,12 +81,10 @@ class Room {
auto getPlatformManager() -> PlatformManager* { return platform_manager_.get(); }
auto getKeyManager() -> KeyManager* { return key_manager_.get(); }
auto getDoorManager() -> DoorManager* { return door_manager_.get(); }
void setItemColors(Uint8 color1, Uint8 color2);
void setTile(int index, int tile_value);
void setCollisionTile(int index, int value);
void setConnection(Border border, const std::string& room_name);
void setTileSet(const std::string& tile_set_file);
void setConveyorBeltDirection(int direction);
[[nodiscard]] auto getTileSetWidth() const -> int { return tile_set_width_; }
#endif
void update(float delta_time);
@@ -100,7 +95,6 @@ class Room {
void tryUnlockDoors(const SDL_FRect& player_rect);
auto checkPlayerOnPlatform(const SDL_FRect& player_collider, float player_vy) -> MovingPlatform*;
void setPaused(bool value);
[[nodiscard]] auto getConveyorBeltDirection() const -> int { return conveyor_belt_direction_; }
[[nodiscard]] auto getTileCollider() const -> const TileCollider&;
[[nodiscard]] auto getCollisionTileMap() const -> const std::vector<int>&;
void updateCollisionBorders(const CollisionMap::AdjacentData& adjacent);
@@ -125,8 +119,6 @@ class Room {
std::string number_;
Uint8 bg_color_{0};
Uint8 item_color1_{Defaults::Game::Room::ITEM_COLOR1};
Uint8 item_color2_{Defaults::Game::Room::ITEM_COLOR2};
std::string upper_room_;
std::string lower_room_;
std::string left_room_;
@@ -135,7 +127,6 @@ class Room {
std::string tile_set_file_;
std::string music_;
std::vector<int> tile_map_;
int conveyor_belt_direction_{0};
bool is_paused_{false};
int tile_set_width_{0};

View File

@@ -140,19 +140,6 @@ void RoomFormat::parseRoomConfig(const fkyaml::node& yaml, Room::Data& room, con
if (room_node.contains("connections")) {
parseRoomConnections(room_node["connections"], room);
}
// Item colors
if (room_node.contains("itemColor1")) {
room.item_color1 = readColorNode(room_node["itemColor1"]);
}
if (room_node.contains("itemColor2")) {
room.item_color2 = readColorNode(room_node["itemColor2"]);
}
// Dirección de la cinta transportadora (left/none/right)
room.conveyor_belt_direction = room_node.contains("conveyorBelt")
? convertAutoSurface(room_node["conveyorBelt"])
: 0;
}
void RoomFormat::parseRoomConnections(const fkyaml::node& conn_node, Room::Data& room) {
@@ -283,7 +270,7 @@ void RoomFormat::parseEnemies(const fkyaml::node& yaml, Room::Data& room, bool v
// Parseo de items
// ============================================================================
auto RoomFormat::parseItemData(const fkyaml::node& item_node, const Room::Data& room) -> Item::Data {
auto RoomFormat::parseItemData(const fkyaml::node& item_node) -> Item::Data {
Item::Data item;
if (item_node.contains("tileSetFile")) {
@@ -304,8 +291,15 @@ auto RoomFormat::parseItemData(const fkyaml::node& item_node, const Room::Data&
? item_node["counter"].get_value_or<int>(0)
: 0;
item.color1 = room.item_color1;
item.color2 = room.item_color2;
// Colores: defaults de Item::Data, override si están en el yaml
if (item_node.contains("color1")) {
item.color1 = readColorNode(item_node["color1"]);
item.color1_overridden = true;
}
if (item_node.contains("color2")) {
item.color2 = readColorNode(item_node["color2"]);
item.color2_overridden = true;
}
return item;
}
@@ -316,7 +310,7 @@ void RoomFormat::parseItems(const fkyaml::node& yaml, Room::Data& room, bool ver
}
for (const auto& item_node : yaml["items"]) {
room.items.push_back(parseItemData(item_node, room));
room.items.push_back(parseItemData(item_node));
}
if (verbose) {
@@ -530,13 +524,6 @@ auto RoomFormat::createDefault() -> Room::Data {
data.left_room = "0";
data.right_room = "0";
// Colores de items por defecto (números, no strings)
data.item_color1 = 11;
data.item_color2 = 12;
// Conveyor belt apagado
data.conveyor_belt_direction = 0;
// Tilemaps del tamaño correcto, vacíos
data.tile_map.resize(Map::WIDTH * Map::HEIGHT, -1);
data.collision_tile_map.resize(Map::WIDTH * Map::HEIGHT, 0);
@@ -553,12 +540,6 @@ auto RoomFormat::roomConnectionToYAML(const std::string& connection) -> std::str
return connection;
}
auto RoomFormat::conveyorBeltToString(int direction) -> std::string {
if (direction < 0) { return "left"; }
if (direction > 0) { return "right"; }
return "none";
}
auto RoomFormat::buildContent(const Room::Data& room_data) -> std::string { // NOLINT(readability-function-cognitive-complexity)
std::ostringstream out;
@@ -587,17 +568,6 @@ auto RoomFormat::buildContent(const Room::Data& room_data) -> std::string { //
out << " left: " << roomConnectionToYAML(room_data.left_room) << "\n";
out << " right: " << roomConnectionToYAML(room_data.right_room) << "\n";
// Colores de items
out << "\n";
out << " # Colores de los objetos\n";
out << " itemColor1: " << static_cast<int>(room_data.item_color1) << "\n";
out << " itemColor2: " << static_cast<int>(room_data.item_color2) << "\n";
// Conveyor belt
out << "\n";
out << " # Dirección de la cinta transportadora: left, none, right\n";
out << " conveyorBelt: " << conveyorBeltToString(room_data.conveyor_belt_direction) << "\n";
// --- Tilemap (MAP_HEIGHT filas × MAP_WIDTH columnas, formato flow) ---
out << "\n";
out << "# Tilemap: " << Map::HEIGHT << " filas x " << Map::WIDTH << " columnas @ " << Tile::SIZE << "px/tile\n";
@@ -684,6 +654,14 @@ auto RoomFormat::buildContent(const Room::Data& room_data) -> std::string { //
out << " counter: " << item.counter << "\n";
}
// color1/color2 solo si son override explícito del default
if (item.color1_overridden) {
out << " color1: " << static_cast<int>(item.color1) << "\n";
}
if (item.color2_overridden) {
out << " color2: " << static_cast<int>(item.color2) << "\n";
}
out << "\n";
}
}

View File

@@ -77,7 +77,7 @@ class RoomFormat {
static auto parseEnemyData(const fkyaml::node& enemy_node) -> Enemy::Data;
static void parseEnemyBoundaries(const fkyaml::node& bounds_node, Enemy::Data& enemy);
static void parseItems(const fkyaml::node& yaml, Room::Data& room, bool verbose);
static auto parseItemData(const fkyaml::node& item_node, const Room::Data& room) -> Item::Data;
static auto parseItemData(const fkyaml::node& item_node) -> Item::Data;
static void parsePlatforms(const fkyaml::node& yaml, Room::Data& room, bool verbose);
static auto parsePlatformData(const fkyaml::node& platform_node) -> MovingPlatform::Data;
static void parseKeys(const fkyaml::node& yaml, Room::Data& room, bool verbose);
@@ -90,6 +90,5 @@ class RoomFormat {
// --- Serialization helpers (solo en debug, los usa saveYAML) ---
static auto buildContent(const Room::Data& room_data) -> std::string;
static auto roomConnectionToYAML(const std::string& connection) -> std::string;
static auto conveyorBeltToString(int direction) -> std::string;
#endif
};

View File

@@ -1,44 +1,32 @@
#include "tilemap_renderer.hpp"
#include "core/rendering/screen.hpp"
#include "core/rendering/sprite/sprite.hpp"
#include "core/rendering/surface.hpp"
#ifdef _DEBUG
#include "core/resources/resource_cache.hpp" // Para Resource::Cache (collision.gif)
#include "core/system/debug.hpp"
#endif
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)
: tile_map_(std::move(tile_map)),
tile_set_width_(tile_set_width),
tileset_surface_(std::move(tileset_surface)),
bg_color_(bg_color),
conveyor_belt_direction_(conveyor_belt_direction) {
bg_color_(bg_color) {
map_surface_ = std::make_shared<Surface>(PlayArea::WIDTH, PlayArea::HEIGHT);
}
void TilemapRenderer::initialize(const std::vector<int>& collision_tile_map) {
setAnimatedTiles(collision_tile_map);
fillMapTexture(collision_tile_map);
}
void TilemapRenderer::update(float delta_time) {
if (is_paused_) { return; }
time_accumulator_ += delta_time;
updateAnimatedTiles();
void TilemapRenderer::update(float /*delta_time*/) {
// De momento no hay tiles animados; el sistema de conveyor belts antiguo se
// eliminó. Cuando se reimplementen como tipos de tile concretos, irá aquí.
}
void TilemapRenderer::render() {
SDL_FRect dest = {.x = 0, .y = 0, .w = PlayArea::WIDTH, .h = PlayArea::HEIGHT};
map_surface_->render(nullptr, &dest);
#ifdef _DEBUG
if (!Debug::get()->isEnabled()) {
renderAnimatedTiles();
}
#else
renderAnimatedTiles();
#endif
}
#ifdef _DEBUG
@@ -62,13 +50,11 @@ void TilemapRenderer::setTile(int index, int tile_value) {
map_surface_->fillRect(&cell, bg_color_);
if (tile_value > -1) {
if (!isAnimatedTile(tile_value)) {
SDL_FRect clip = {.x = static_cast<float>((tile_value % tile_set_width_) * TILE_SIZE),
.y = static_cast<float>((tile_value / tile_set_width_) * TILE_SIZE),
.w = static_cast<float>(TILE_SIZE),
.h = static_cast<float>(TILE_SIZE)};
tileset_surface_->render(col * TILE_SIZE, row * TILE_SIZE, &clip);
}
SDL_FRect clip = {.x = static_cast<float>((tile_value % tile_set_width_) * TILE_SIZE),
.y = static_cast<float>((tile_value / tile_set_width_) * TILE_SIZE),
.w = static_cast<float>(TILE_SIZE),
.h = static_cast<float>(TILE_SIZE)};
tileset_surface_->render(col * TILE_SIZE, row * TILE_SIZE, &clip);
}
Screen::get()->setRendererSurface(previous_renderer);
@@ -106,20 +92,18 @@ void TilemapRenderer::fillMapTexture(const std::vector<int>& collision_tile_map)
for (int y = 0; y < MAP_HEIGHT; ++y) {
for (int x = 0; x < MAP_WIDTH; ++x) {
const int INDEX = (y * MAP_WIDTH) + x;
// Los tiles animados no se pintan en la textura estática
const bool HAS_TILE = tile_map_[INDEX] > -1;
if (!HAS_TILE) { continue; }
if (HAS_TILE && !isAnimatedTile(tile_map_[INDEX])) {
clip.x = (tile_map_[INDEX] % tile_set_width_) * TILE_SIZE;
clip.y = (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;
#ifdef _DEBUG
if (!Debug::get()->isEnabled()) {
tileset_surface_->render(x * TILE_SIZE, y * TILE_SIZE, &clip);
}
#else
if (!Debug::get()->isEnabled()) {
tileset_surface_->render(x * TILE_SIZE, y * TILE_SIZE, &clip);
#endif
}
#else
tileset_surface_->render(x * TILE_SIZE, y * TILE_SIZE, &clip);
#endif
}
}
@@ -131,50 +115,3 @@ void TilemapRenderer::fillMapTexture(const std::vector<int>& collision_tile_map)
#endif
Screen::get()->setRendererSurface(previous_renderer);
}
// Localiza tiles animados (conveyor belts) usando el collision_tile_map
void TilemapRenderer::setAnimatedTiles(const std::vector<int>& collision_tile_map) {
for (int i = 0; i < static_cast<int>(tile_map_.size()); ++i) {
// Un tile es animado si su valor en el collision tilemap es COLLISION_ANIMATED (6)
if (i < static_cast<int>(collision_tile_map.size()) && collision_tile_map[i] == COLLISION_ANIMATED) {
const int X = (i % MAP_WIDTH) * TILE_SIZE;
const int Y = (i / MAP_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;
AnimatedTile at;
at.sprite = std::make_shared<Sprite>(tileset_surface_, X, Y, TILE_SIZE, TILE_SIZE);
at.sprite->setClip(XC, YC, TILE_SIZE, TILE_SIZE);
at.x_orig = XC;
animated_tiles_.push_back(at);
}
}
}
void TilemapRenderer::updateAnimatedTiles() {
const int NUM_FRAMES = 4;
const int CURRENT_FRAME = static_cast<int>(time_accumulator_ / CONVEYOR_FRAME_DURATION) % NUM_FRAMES;
int offset = 0;
if (conveyor_belt_direction_ == -1) {
offset = CURRENT_FRAME * TILE_SIZE;
} else {
offset = (NUM_FRAMES - 1 - CURRENT_FRAME) * TILE_SIZE;
}
for (auto& a : animated_tiles_) {
SDL_FRect rect = a.sprite->getClip();
rect.x = a.x_orig + offset;
a.sprite->setClip(rect);
}
}
void TilemapRenderer::renderAnimatedTiles() {
for (const auto& a : animated_tiles_) {
a.sprite->render();
}
}
auto TilemapRenderer::isAnimatedTile(int tile_value) const -> bool {
return (tile_value >= ANIMATED_TILE_ROW * tile_set_width_) && (tile_value < (ANIMATED_TILE_ROW + 1) * tile_set_width_);
}

View File

@@ -8,11 +8,10 @@
#include "utils/defines.hpp"
class Surface;
class Sprite;
class TilemapRenderer {
public:
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);
~TilemapRenderer() = default;
TilemapRenderer(const TilemapRenderer&) = delete;
@@ -33,35 +32,19 @@ class TilemapRenderer {
[[nodiscard]] auto getMapSurface() const -> std::shared_ptr<Surface> { return map_surface_; }
private:
struct AnimatedTile {
std::shared_ptr<Sprite> sprite{nullptr};
int x_orig{0};
};
static constexpr int TILE_SIZE = Tile::SIZE;
static constexpr int MAP_WIDTH = Map::WIDTH;
static constexpr int MAP_HEIGHT = Map::HEIGHT;
static constexpr int PLAY_AREA_WIDTH = PlayArea::WIDTH;
static constexpr int PLAY_AREA_HEIGHT = PlayArea::HEIGHT;
static constexpr float CONVEYOR_FRAME_DURATION = 0.05F;
static constexpr int COLLISION_ANIMATED = 6; // Valor del tile de conveyor en el collision tilemap
static constexpr int ANIMATED_TILE_ROW = 18; // Fila del tileset que contiene los tiles animados
[[nodiscard]] auto isAnimatedTile(int tile_value) const -> bool;
std::vector<int> tile_map_;
int tile_set_width_;
std::shared_ptr<Surface> tileset_surface_;
Uint8 bg_color_{0};
int conveyor_belt_direction_;
std::shared_ptr<Surface> map_surface_;
std::vector<AnimatedTile> animated_tiles_;
float time_accumulator_{0.0F};
bool is_paused_{false};
void fillMapTexture(const std::vector<int>& collision_tile_map);
void setAnimatedTiles(const std::vector<int>& collision_tile_map);
void updateAnimatedTiles();
void renderAnimatedTiles();
};