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

@@ -273,7 +273,6 @@ categories:
completions:
SET FLIP: [ON, OFF]
SET MIRROR: [ON, OFF]
SET CONVEYOR: [LEFT, NONE, RIGHT]
- name: CHEATS
scope: [game, editor]

View File

@@ -8,13 +8,6 @@ room:
left: 06.yaml
right: 02.yaml
# Colores de los objetos
itemColor1: 12
itemColor2: 6
# Dirección de la cinta transportadora: left, none, right
conveyorBelt: none
# Tilemap: 21 filas x 32 columnas @ 8px/tile
tilemap:
# Mapa de dibujo (indices de tiles, -1 = vacio)

View File

@@ -8,13 +8,6 @@ room:
left: 01.yaml
right: 03.yaml
# Colores de los objetos
itemColor1: 12
itemColor2: 13
# Dirección de la cinta transportadora: left, none, right
conveyorBelt: none
# Tilemap: 21 filas x 32 columnas @ 8px/tile
tilemap:
# Mapa de dibujo (indices de tiles, -1 = vacio)
@@ -87,6 +80,7 @@ items:
tile: 2
position: {x: 4, y: 6}
counter: 1
color2: 13
# Plataformas móviles en esta habitación
platforms:

View File

@@ -8,13 +8,6 @@ room:
left: 02.yaml
right: null
# Colores de los objetos
itemColor1: 11
itemColor2: 12
# Dirección de la cinta transportadora: left, none, right
conveyorBelt: left
# Tilemap: 21 filas x 32 columnas @ 8px/tile
tilemap:
# Mapa de dibujo (indices de tiles, -1 = vacio)
@@ -78,9 +71,13 @@ items:
- tileSetFile: items.gif
tile: 0
position: {x: 10, y: 11}
color1: 11
color2: 12
- tileSetFile: items.gif
tile: 0
position: {x: 13, y: 11}
counter: 1
color1: 11
color2: 12

View File

@@ -8,13 +8,6 @@ room:
left: 05.yaml
right: null
# Colores de los objetos
itemColor1: 0
itemColor2: 0
# Dirección de la cinta transportadora: left, none, right
conveyorBelt: none
# Tilemap: 21 filas x 32 columnas @ 8px/tile
tilemap:
# Mapa de dibujo (indices de tiles, -1 = vacio)

View File

@@ -8,13 +8,6 @@ room:
left: null
right: 04.yaml
# Colores de los objetos
itemColor1: 11
itemColor2: 12
# Dirección de la cinta transportadora: left, none, right
conveyorBelt: none
# Tilemap: 21 filas x 32 columnas @ 8px/tile
tilemap:
# Mapa de dibujo (indices de tiles, -1 = vacio)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -112,8 +112,6 @@ namespace Defaults::Localization {
namespace Defaults::Game::Room {
constexpr const char* INITIAL = "03.yaml"; // Habitación de inicio
constexpr Uint8 ITEM_COLOR1 = 12; // Color principal de los items por defecto
constexpr Uint8 ITEM_COLOR2 = 6; // Color secundario de los items por defecto
} // namespace Defaults::Game::Room
namespace Defaults::Game::Player {

View File

@@ -11,7 +11,6 @@
#include <iostream> // Para cout
#include <set> // Para set
#include "external/fkyaml_node.hpp" // Para fkyaml::node (loadSettings)
#include "core/input/mouse.hpp" // Para Mouse
#include "core/rendering/render_info.hpp" // Para RenderInfo
#include "core/rendering/screen.hpp" // Para Screen
@@ -19,8 +18,8 @@
#include "core/resources/resource_cache.hpp" // Para Resource::Cache
#include "core/resources/resource_list.hpp" // Para Resource::List
#include "core/resources/resource_types.hpp" // Para RoomResource
#include "external/fkyaml_node.hpp" // Para fkyaml::node (loadSettings)
#include "game/editor/editor_statusbar.hpp" // Para EditorStatusBar
#include "game/gameplay/room_format.hpp" // Para RoomFormat
#include "game/entities/player.hpp" // Para Player
#include "game/game_control.hpp" // Para GameControl
#include "game/gameplay/door_manager.hpp" // Para DoorManager
@@ -29,6 +28,7 @@
#include "game/gameplay/key_manager.hpp" // Para KeyManager
#include "game/gameplay/platform_manager.hpp" // Para PlatformManager
#include "game/gameplay/room.hpp" // Para Room
#include "game/gameplay/room_format.hpp" // Para RoomFormat
#include "game/gameplay/zone.hpp" // Para Zone::Data
#include "game/gameplay/zone_manager.hpp" // Para ZoneManager
#include "game/options.hpp" // Para Options
@@ -294,10 +294,7 @@ auto MapEditor::revert() -> std::string {
auto* item_mgr = room_->getItemManager();
item_mgr->clear();
for (const auto& i : room_data_.items) {
Item::Data item_copy = i;
item_copy.color1 = room_data_.item_color1;
item_copy.color2 = room_data_.item_color2;
item_mgr->addItem(std::make_shared<Item>(item_copy));
item_mgr->addItem(std::make_shared<Item>(i));
}
auto* platform_mgr = room_->getPlatformManager();
@@ -306,8 +303,6 @@ auto MapEditor::revert() -> std::string {
platform_mgr->addPlatform(std::make_shared<MovingPlatform>(p));
}
room_->setItemColors(room_data_.item_color1, room_data_.item_color2);
// Restaurar el tilemap completo
for (int i = 0; i < static_cast<int>(room_data_.tile_map.size()); ++i) {
room_->setTile(i, room_data_.tile_map[i]);
@@ -1266,7 +1261,9 @@ void MapEditor::updateStatusBarInfo() { // NOLINT(readability-function-cognitiv
const auto& it = room_data_.items[selection_.index];
line2 = "item " + std::to_string(selection_.index) + ": tile=" + std::to_string(it.tile) +
" counter=" + std::to_string(it.counter);
line3 = "tileset: " + it.tile_set_file;
std::string c1_marker = it.color1_overridden ? "*" : "";
std::string c2_marker = it.color2_overridden ? "*" : "";
line3 = "col:" + std::to_string(it.color1) + c1_marker + "/" + std::to_string(it.color2) + c2_marker;
}
break;
@@ -1305,19 +1302,11 @@ void MapEditor::updateStatusBarInfo() { // NOLINT(readability-function-cognitiv
case EntityType::NONE: {
// Propiedades de la habitación
std::string conv = "none";
if (room_data_.conveyor_belt_direction < 0) {
conv = "left";
} else if (room_data_.conveyor_belt_direction > 0) {
conv = "right";
}
std::string ts_marker = room_data_.tile_set_overridden ? " (ts*)" : "";
std::string mu_marker = room_data_.music_overridden ? " (mu*)" : "";
line2 = "zone:" + room_data_.zone + ts_marker + mu_marker + " conv:" + conv;
line2 = "zone:" + room_data_.zone + ts_marker + mu_marker;
line3 = "u:" + conn(room_data_.upper_room) + " d:" + conn(room_data_.lower_room) +
" l:" + conn(room_data_.left_room) + " r:" + conn(room_data_.right_room) +
" itm:" + std::to_string(room_data_.item_color1) + "/" + std::to_string(room_data_.item_color2);
" l:" + conn(room_data_.left_room) + " r:" + conn(room_data_.right_room);
break;
}
}
@@ -1349,7 +1338,7 @@ auto MapEditor::getSetCompletions() const -> std::vector<std::string> {
case EntityType::ENEMY:
return {"ANIMATION", "VX", "VY", "FLIP", "MIRROR"};
case EntityType::ITEM:
return {"TILE", "COUNTER"};
return {"TILE", "COUNTER", "COLOR1", "COLOR2"};
case EntityType::PLATFORM:
return {"ANIMATION", "SPEED", "LOOP", "EASING"};
case EntityType::KEY:
@@ -1357,7 +1346,7 @@ auto MapEditor::getSetCompletions() const -> std::vector<std::string> {
case EntityType::DOOR:
return {"ID", "ANIMATION"};
default:
return {"ZONE", "ITEMCOLOR1", "ITEMCOLOR2", "CONVEYOR", "TILESET", "MUSIC", "UP", "DOWN", "LEFT", "RIGHT"};
return {"ZONE", "TILESET", "MUSIC", "UP", "DOWN", "LEFT", "RIGHT"};
}
}
@@ -1534,36 +1523,6 @@ auto MapEditor::setRoomProperty(const std::string& property, const std::string&
std::string val = toLower(value);
if (property == "ITEMCOLOR1") {
auto color = static_cast<Uint8>(safeStoi(val, 0));
room_data_.item_color1 = color;
room_->setItemColors(room_data_.item_color1, room_data_.item_color2);
autosave();
return "itemcolor1: " + std::to_string(color);
}
if (property == "ITEMCOLOR2") {
auto color = static_cast<Uint8>(safeStoi(val, 0));
room_data_.item_color2 = color;
room_->setItemColors(room_data_.item_color1, room_data_.item_color2);
autosave();
return "itemcolor2: " + std::to_string(color);
}
if (property == "CONVEYOR") {
if (val == "left") {
room_data_.conveyor_belt_direction = -1;
} else if (val == "right") {
room_data_.conveyor_belt_direction = 1;
} else {
room_data_.conveyor_belt_direction = 0;
val = "none";
}
room_->setConveyorBeltDirection(room_data_.conveyor_belt_direction);
autosave();
return "conveyor: " + val;
}
if (property == "ZONE") {
const Zone::Data* zone = ZoneManager::get()->getZone(val);
if (zone == nullptr) { return "Unknown zone: " + val; }
@@ -1830,10 +1789,15 @@ auto MapEditor::createNewRoom(const std::string& direction) -> std::string { //
// Sincronizar con Resource::Cache::rooms_ (datos crudos)
auto cached = Resource::Cache::get()->getRoom(room_path_);
if (cached) {
if (direction == "UP") { cached->upper_room = new_name; }
else if (direction == "DOWN") { cached->lower_room = new_name; }
else if (direction == "LEFT") { cached->left_room = new_name; }
else if (direction == "RIGHT") { cached->right_room = new_name; }
if (direction == "UP") {
cached->upper_room = new_name;
} else if (direction == "DOWN") {
cached->lower_room = new_name;
} else if (direction == "LEFT") {
cached->left_room = new_name;
} else if (direction == "RIGHT") {
cached->right_room = new_name;
}
}
}
@@ -1949,7 +1913,45 @@ auto MapEditor::setItemProperty(const std::string& property, const std::string&
return "counter: " + std::to_string(item.counter);
}
return "Unknown property: " + property + " (use: tile, counter)";
if (property == "COLOR1") {
// "reset" / "none" limpia el override y vuelve al default
const std::string LOWER = toLower(value);
if (LOWER == "reset" || LOWER == "none") {
item.color1 = Item::DEFAULT_COLOR1;
item.color1_overridden = false;
// Recrear el sprite vivo con los colores nuevos
room_->getItemManager()->getItem(selection_.index) = std::make_shared<Item>(item);
autosave();
return "color1: (default)";
}
try {
item.color1 = static_cast<Uint8>(std::stoi(value));
} catch (...) { return "Invalid value: " + value; }
item.color1_overridden = true;
room_->getItemManager()->getItem(selection_.index) = std::make_shared<Item>(item);
autosave();
return "color1: " + std::to_string(item.color1);
}
if (property == "COLOR2") {
const std::string LOWER = toLower(value);
if (LOWER == "reset" || LOWER == "none") {
item.color2 = Item::DEFAULT_COLOR2;
item.color2_overridden = false;
room_->getItemManager()->getItem(selection_.index) = std::make_shared<Item>(item);
autosave();
return "color2: (default)";
}
try {
item.color2 = static_cast<Uint8>(std::stoi(value));
} catch (...) { return "Invalid value: " + value; }
item.color2_overridden = true;
room_->getItemManager()->getItem(selection_.index) = std::make_shared<Item>(item);
autosave();
return "color2: " + std::to_string(item.color2);
}
return "Unknown property: " + property + " (use: tile, counter, color1, color2)";
}
// Abre el tile picker para seleccionar un tile
@@ -1965,8 +1967,11 @@ void MapEditor::openTilePicker(const std::string& tileset_name, int current_tile
room_->getItemManager()->getItem(selection_.index)->setTile(tile);
autosave();
};
// Pasar color de fondo de la habitación + color de sustitución del item
tile_picker_.open(tileset_name, current_tile, room_data_.bg_color, 1, room_data_.item_color1);
// Pasar color de fondo de la habitación + color del item seleccionado para previsualizarlo
Uint8 preview_color = hasSelectedItem()
? room_data_.items[selection_.index].color1
: Item::DEFAULT_COLOR1;
tile_picker_.open(tileset_name, current_tile, room_data_.bg_color, 1, preview_color);
}
// Crea un nuevo item con valores por defecto, centrado en la habitación
@@ -1979,8 +1984,7 @@ auto MapEditor::addItem() -> std::string {
new_item.x = PlayArea::CENTER_X;
new_item.y = PlayArea::CENTER_Y;
new_item.counter = 0;
new_item.color1 = room_data_.item_color1;
new_item.color2 = room_data_.item_color2;
// Los colores quedan en sus defaults (Item::DEFAULT_COLOR1/2)
room_data_.items.push_back(new_item);
room_->getItemManager()->addItem(std::make_shared<Item>(new_item));

View File

@@ -55,17 +55,3 @@ void Item::setTile(int tile) {
sprite_->setClip((tile % TILESET_COLUMNS) * ITEM_SIZE, (tile / TILESET_COLUMNS) * ITEM_SIZE, ITEM_SIZE, ITEM_SIZE);
}
#endif
// Asigna los colores del objeto
void Item::setColors(Uint8 col1, Uint8 col2) {
// Reinicializa el vector de colores
color_.clear();
// Añade el primer color
color_.push_back(col1);
color_.push_back(col1);
// Añade el segundo color
color_.push_back(col2);
color_.push_back(col2);
}

View File

@@ -9,14 +9,19 @@ class Sprite;
class Item {
public:
static constexpr Uint8 DEFAULT_COLOR1 = 12; // Color principal por defecto
static constexpr Uint8 DEFAULT_COLOR2 = 6; // Color secundario por defecto
struct Data {
std::string tile_set_file; // Ruta al fichero con los gráficos del item
float x{0.0F}; // Posición del item en pantalla
float y{0.0F}; // Posición del item en pantalla
int tile{0}; // Número de tile dentro de la textura
int counter{0}; // Contador inicial. Es el que lo hace cambiar de color
Uint8 color1{0}; // Uno de los dos colores que se utiliza para el item
Uint8 color2{0}; // Uno de los dos colores que se utiliza para el item
Uint8 color1{DEFAULT_COLOR1}; // Color principal del item (override del default si está en el yaml)
Uint8 color2{DEFAULT_COLOR2}; // Color secundario del item
bool color1_overridden{false}; // True si el yaml tenía color1 explícito
bool color2_overridden{false}; // True si el yaml tenía color2 explícito
};
explicit Item(const Data& item); // Constructor
@@ -28,7 +33,6 @@ class Item {
void setPaused(bool paused) { is_paused_ = paused; } // Pausa/despausa el item
auto getCollider() -> SDL_FRect& { return collider_; } // Obtiene el rectangulo de colision del objeto
auto getPos() -> SDL_FPoint; // Obtiene su ubicación
void setColors(Uint8 col1, Uint8 col2); // Asigna los colores del objeto
#ifdef _DEBUG
void setPosition(float x, float y); // Establece la posición del item (para editor)
void setTile(int tile); // Cambia el tile del item (para editor)

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,7 +55,6 @@ 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)
// Copia el centro (room actual) al mapa extendido. Los bordes quedan como EMPTY (0).

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,14 +50,12 @@ 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);
}
}
Screen::get()->setRendererSurface(previous_renderer);
}
@@ -106,10 +92,9 @@ 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;
#ifdef _DEBUG
@@ -121,7 +106,6 @@ void TilemapRenderer::fillMapTexture(const std::vector<int>& collision_tile_map)
#endif
}
}
}
#ifdef _DEBUG
// En modo debug, pintar el collision tilemap en vez de las líneas de colisión antiguas
@@ -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();
};

View File

@@ -1031,8 +1031,7 @@ void Game::updateMusicForRoom() {
if (target.empty()) { return; }
// Reproducir si no coincide la pista actual o si está parada
if (Audio::get()->getCurrentMusicName() != target
|| Audio::get()->getMusicState() == Audio::MusicState::STOPPED) {
if (Audio::get()->getCurrentMusicName() != target || Audio::get()->getMusicState() == Audio::MusicState::STOPPED) {
Audio::get()->playMusic(target);
}
}