collision map

This commit is contained in:
2026-04-06 20:27:35 +02:00
parent ef04500a44
commit 98715ef3a7
36 changed files with 489 additions and 297 deletions

View File

@@ -121,9 +121,10 @@ auto MapEditor::showGrid(bool show) -> std::string {
return show ? "Grid ON" : "Grid OFF";
}
// Parsea un color como índice numérico
static auto parseColor(const std::string& value) -> Uint8 {
return static_cast<Uint8>(safeStoi(value, 0));
auto MapEditor::setEditingCollision(bool collision) -> std::string {
editing_collision_ = collision;
brush_tile_ = NO_BRUSH; // Resetear brush al cambiar de modo
return editing_collision_ ? "Editing: collision" : "Editing: draw";
}
void MapEditor::toggleMiniMap() {
@@ -225,6 +226,12 @@ void MapEditor::enter(std::shared_ptr<Room> room, std::shared_ptr<Player> player
selected_item_ = -1;
brush_tile_ = NO_BRUSH;
painting_ = false;
editing_collision_ = false;
// Asegurar que collision_tile_map tiene el tamaño correcto
if (room_data_.collision_tile_map.size() != static_cast<size_t>(Map::WIDTH * Map::HEIGHT)) {
room_data_.collision_tile_map.resize(Map::WIDTH * Map::HEIGHT, 0);
}
active_ = true;
std::cout << "MapEditor: ON (room " << room_path_ << ")\n";
@@ -332,10 +339,20 @@ void MapEditor::update(float delta_time) {
// Si estamos pintando tiles, pintar en la posición actual del ratón
if (painting_ && brush_tile_ != NO_BRUSH) {
int tile_index = (mouse_tile_y_ * 32) + mouse_tile_x_;
if (tile_index >= 0 && tile_index < static_cast<int>(room_data_.tile_map.size())) {
if (room_data_.tile_map[tile_index] != brush_tile_) {
room_data_.tile_map[tile_index] = brush_tile_;
room_->setTile(tile_index, brush_tile_);
if (editing_collision_) {
// Pintar en el mapa de colisiones
if (tile_index >= 0 && tile_index < static_cast<int>(room_data_.collision_tile_map.size())) {
if (room_data_.collision_tile_map[tile_index] != brush_tile_) {
room_data_.collision_tile_map[tile_index] = brush_tile_;
}
}
} else {
// Pintar en el mapa de dibujo
if (tile_index >= 0 && tile_index < static_cast<int>(room_data_.tile_map.size())) {
if (room_data_.tile_map[tile_index] != brush_tile_) {
room_data_.tile_map[tile_index] = brush_tile_;
room_->setTile(tile_index, brush_tile_);
}
}
}
}
@@ -351,6 +368,28 @@ void MapEditor::update(float delta_time) {
void MapEditor::render() {
// El tilemap ya ha sido renderizado por Game::renderPlaying() antes de llamar aquí
// Si estamos editando colisiones, superponer el mapa de colisiones
if (editing_collision_) {
auto collision_surface = Resource::Cache::get()->getSurface("collision.gif");
if (collision_surface) {
const int TILE_W = Tile::SIZE;
for (int y = 0; y < Map::HEIGHT; ++y) {
for (int x = 0; x < Map::WIDTH; ++x) {
int index = (y * Map::WIDTH) + x;
if (index >= static_cast<int>(room_data_.collision_tile_map.size())) { continue; }
int tile = room_data_.collision_tile_map[index];
if (tile <= 0) { continue; } // 0 = vacío, no dibujar
SDL_FRect clip = {
.x = static_cast<float>(tile * TILE_W),
.y = 0,
.w = static_cast<float>(TILE_W),
.h = static_cast<float>(TILE_W)};
collision_surface->render(x * TILE_W, y * TILE_W, &clip);
}
}
}
}
// Grid (debajo de todo)
if (settings_.grid) {
renderGrid();
@@ -418,22 +457,41 @@ void MapEditor::handleEvent(const SDL_Event& event) { // NOLINT(readability-fun
return;
}
// Click derecho: abrir TilePicker del mapa
// 7: alternar entre draw y collision
if (event.type == SDL_EVENT_KEY_DOWN && event.key.key == SDLK_7 && static_cast<int>(event.key.repeat) == 0) {
setEditingCollision(!editing_collision_);
return;
}
// Click derecho: abrir TilePicker
if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN && event.button.button == SDL_BUTTON_RIGHT) {
// Deseleccionar entidades
selected_enemy_ = -1;
selected_item_ = -1;
// Tile bajo el cursor como tile actual del picker
int tile_index = (mouse_tile_y_ * 32) + mouse_tile_x_;
int current = (tile_index >= 0 && tile_index < static_cast<int>(room_data_.tile_map.size()))
? room_data_.tile_map[tile_index]
: -1;
if (editing_collision_) {
// Abrir tile picker del collision tileset
int tile_index = (mouse_tile_y_ * 32) + mouse_tile_x_;
int current = (tile_index >= 0 && tile_index < static_cast<int>(room_data_.collision_tile_map.size()))
? room_data_.collision_tile_map[tile_index]
: 0;
tile_picker_.on_select = [this](int tile) {
brush_tile_ = tile;
};
tile_picker_.open(room_->getTileSetFile(), current, room_data_.bg_color);
tile_picker_.on_select = [this](int tile) {
brush_tile_ = tile;
};
tile_picker_.open("collision.gif", current, 0);
} else {
// Abrir tile picker del mapa de dibujo
int tile_index = (mouse_tile_y_ * 32) + mouse_tile_x_;
int current = (tile_index >= 0 && tile_index < static_cast<int>(room_data_.tile_map.size()))
? room_data_.tile_map[tile_index]
: -1;
tile_picker_.on_select = [this](int tile) {
brush_tile_ = tile;
};
tile_picker_.open(room_->getTileSetFile(), current, room_data_.bg_color);
}
return;
}
@@ -463,9 +521,15 @@ void MapEditor::handleEvent(const SDL_Event& event) { // NOLINT(readability-fun
// Pintar tile y entrar en modo painting
painting_ = true;
int tile_index = (mouse_tile_y_ * 32) + mouse_tile_x_;
if (tile_index >= 0 && tile_index < static_cast<int>(room_data_.tile_map.size())) {
room_data_.tile_map[tile_index] = brush_tile_;
room_->setTile(tile_index, brush_tile_);
if (editing_collision_) {
if (tile_index >= 0 && tile_index < static_cast<int>(room_data_.collision_tile_map.size())) {
room_data_.collision_tile_map[tile_index] = brush_tile_;
}
} else {
if (tile_index >= 0 && tile_index < static_cast<int>(room_data_.tile_map.size())) {
room_data_.tile_map[tile_index] = brush_tile_;
room_->setTile(tile_index, brush_tile_);
}
}
return;
}
@@ -1329,6 +1393,7 @@ auto MapEditor::createNewRoom(const std::string& direction) -> std::string { //
new_room.right_room = "0";
new_room.conveyor_belt_direction = 0;
new_room.tile_map.resize(Map::WIDTH * Map::HEIGHT, -1);
new_room.collision_tile_map.resize(Map::WIDTH * Map::HEIGHT, 0);
// Conexión recíproca: la nueva room conecta de vuelta a la actual
if (direction == "UP") {

View File

@@ -50,6 +50,7 @@ class MapEditor {
// Opciones del editor (llamados desde console_commands / teclas)
auto showInfo(bool show) -> std::string;
auto showGrid(bool show) -> std::string;
auto setEditingCollision(bool collision) -> std::string;
[[nodiscard]] auto isGridEnabled() const -> bool { return settings_.grid; }
void toggleMiniMap();
void setReenter(bool value) { reenter_ = value; }
@@ -122,6 +123,7 @@ class MapEditor {
static constexpr int ERASER_BRUSH = -1; // Brush borrador (pinta tile vacío = -1)
int brush_tile_{NO_BRUSH}; // Tile activo para pintar
bool painting_{false}; // true mientras se está pintando con click izquierdo mantenido
bool editing_collision_{false}; // true = editando collision tilemap, false = editando draw tilemap
// Datos de la habitación
Room::Data room_data_;

View File

@@ -86,7 +86,7 @@ class MiniMap {
float view_start_y_{0.0F};
// Constantes
static constexpr int ROOM_W = Map::WIDTH; // Ancho de una room en pixels del minimapa (1 pixel por tile)
static constexpr int ROOM_W = Map::WIDTH; // Ancho de una room en pixels del minimapa (1 pixel por tile)
static constexpr int ROOM_H = Map::HEIGHT; // Alto de una room en pixels del minimapa (1 pixel por tile)
static constexpr int BORDER = 1; // Borde alrededor de cada room
static constexpr int CELL_W = ROOM_W + (BORDER * 2); // Room + borde

View File

@@ -37,7 +37,7 @@ auto RoomSaver::conveyorBeltToString(int direction) -> std::string {
// Genera el YAML completo como texto con formato compacto
auto RoomSaver::buildYAML(const fkyaml::node& original_yaml, const Room::Data& room_data) -> std::string { // NOLINT(readability-function-cognitive-complexity)
(void)original_yaml; // Ya no se usa; mantenido para compatibilidad con la firma de saveYAML
(void)original_yaml; // Ya no se usa; mantenido para compatibilidad con la firma de saveYAML
std::ostringstream out;
// --- Sección room ---
@@ -70,10 +70,13 @@ auto RoomSaver::buildYAML(const fkyaml::node& original_yaml, const Room::Data& r
// --- 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";
out << "# Índices de tiles (-1 = vacío)\n";
out << "tilemap:\n";
// Mapa de dibujo
out << " # Mapa de dibujo (indices de tiles, -1 = vacio)\n";
out << " draw:\n";
for (int row = 0; row < Map::HEIGHT; ++row) {
out << " - [";
out << " - [";
for (int col = 0; col < Map::WIDTH; ++col) {
int index = (row * Map::WIDTH) + col;
if (index < static_cast<int>(room_data.tile_map.size())) {
@@ -86,6 +89,23 @@ auto RoomSaver::buildYAML(const fkyaml::node& original_yaml, const Room::Data& r
out << "]\n";
}
// Mapa de colisiones
out << " # Mapa de colisiones (0 = vacio, 1 = solido)\n";
out << " collision:\n";
for (int row = 0; row < Map::HEIGHT; ++row) {
out << " - [";
for (int col = 0; col < Map::WIDTH; ++col) {
int index = (row * Map::WIDTH) + col;
if (index < static_cast<int>(room_data.collision_tile_map.size())) {
out << room_data.collision_tile_map[index];
} else {
out << 0;
}
if (col < Map::WIDTH - 1) { out << ", "; }
}
out << "]\n";
}
// --- Enemigos ---
if (!room_data.enemies.empty()) {
out << "\n";