eliminar entrades legacy del fitxer de mapa
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
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{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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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};
|
||||
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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_);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user