començem a treballar en el editor

This commit is contained in:
2026-04-02 10:28:19 +02:00
parent 0bfb535d4d
commit a2caf95005
10 changed files with 415 additions and 4 deletions

View File

@@ -0,0 +1,69 @@
#ifdef _DEBUG
#include "game/editor/editor_statusbar.hpp"
#include <string> // Para to_string
#include "core/rendering/screen.hpp" // Para Screen
#include "core/rendering/surface.hpp" // Para Surface
#include "core/rendering/text.hpp" // Para Text
#include "core/resources/resource_cache.hpp" // Para Resource::Cache
#include "game/options.hpp" // Para Options::game
#include "utils/defines.hpp" // Para Tile::SIZE
#include "utils/utils.hpp" // Para stringToColor
// Constructor
EditorStatusBar::EditorStatusBar(const std::string& room_number, const std::string& room_name)
: room_number_(room_number),
room_name_(room_name) {
const float SURFACE_WIDTH = Options::game.width;
constexpr float SURFACE_HEIGHT = 6.0F * Tile::SIZE; // 48 pixels, igual que el scoreboard
surface_ = std::make_shared<Surface>(SURFACE_WIDTH, SURFACE_HEIGHT);
surface_dest_ = {.x = 0, .y = Options::game.height - SURFACE_HEIGHT, .w = SURFACE_WIDTH, .h = SURFACE_HEIGHT};
}
// Pinta la barra de estado en pantalla
void EditorStatusBar::render() {
surface_->render(nullptr, &surface_dest_);
}
// Actualiza la barra de estado
void EditorStatusBar::update([[maybe_unused]] float delta_time) {
fillTexture();
}
// Establece las coordenadas del ratón en tiles
void EditorStatusBar::setMouseTile(int tile_x, int tile_y) {
mouse_tile_x_ = tile_x;
mouse_tile_y_ = tile_y;
}
// Dibuja los elementos en la surface
void EditorStatusBar::fillTexture() {
auto previous_renderer = Screen::get()->getRendererSurface();
Screen::get()->setRendererSurface(surface_);
surface_->clear(stringToColor("black"));
auto text = Resource::Cache::get()->getText("smb2");
const Uint8 LABEL_COLOR = stringToColor("bright_cyan");
const Uint8 VALUE_COLOR = stringToColor("white");
// Línea 1: Número y nombre de la habitación
const std::string ROOM_TEXT = room_number_ + " " + room_name_;
text->writeColored(LEFT_X, LINE1_Y, ROOM_TEXT, LABEL_COLOR);
// Línea 2: Coordenadas del ratón en tiles
const std::string TILE_X_STR = (mouse_tile_x_ < 10 ? "0" : "") + std::to_string(mouse_tile_x_);
const std::string TILE_Y_STR = (mouse_tile_y_ < 10 ? "0" : "") + std::to_string(mouse_tile_y_);
text->writeColored(LEFT_X, LINE2_Y, "TILE:", LABEL_COLOR);
text->writeColored(LEFT_X + 48, LINE2_Y, TILE_X_STR + "," + TILE_Y_STR, VALUE_COLOR);
// Indicador de modo editor
text->writeColored(176, LINE2_Y, "EDITOR", stringToColor("bright_green"));
Screen::get()->setRendererSurface(previous_renderer);
}
#endif // _DEBUG

View File

@@ -0,0 +1,40 @@
#pragma once
#ifdef _DEBUG
#include <SDL3/SDL.h>
#include <memory> // Para shared_ptr
#include <string> // Para string
class Surface;
class EditorStatusBar {
public:
EditorStatusBar(const std::string& room_number, const std::string& room_name);
~EditorStatusBar() = default;
void render();
void update(float delta_time);
void setMouseTile(int tile_x, int tile_y);
private:
void fillTexture(); // Dibuja los elementos en la surface
// Constantes de posición (en pixels dentro de la surface de 256x48)
static constexpr int LINE1_Y = 8; // Nombre de la habitación
static constexpr int LINE2_Y = 24; // Coordenadas del ratón
static constexpr int LEFT_X = 8; // Margen izquierdo
// Objetos
std::shared_ptr<Surface> surface_; // Surface donde dibujar la barra
SDL_FRect surface_dest_{}; // Rectángulo destino en pantalla
// Variables
std::string room_number_; // Número de la habitación
std::string room_name_; // Nombre de la habitación
int mouse_tile_x_{0}; // Coordenada X del ratón en tiles
int mouse_tile_y_{0}; // Coordenada Y del ratón en tiles
};
#endif // _DEBUG

View File

@@ -0,0 +1,147 @@
#ifdef _DEBUG
#include "game/editor/map_editor.hpp"
#include <SDL3/SDL.h>
#include <iostream> // Para cout
#include "core/input/mouse.hpp" // Para Mouse
#include "core/rendering/screen.hpp" // Para Screen
#include "game/editor/editor_statusbar.hpp" // Para EditorStatusBar
#include "game/entities/player.hpp" // Para Player
#include "game/gameplay/room.hpp" // Para Room
#include "game/options.hpp" // Para Options
#include "utils/defines.hpp" // Para Tile::SIZE, PlayArea
// Singleton
MapEditor* MapEditor::instance_ = nullptr;
void MapEditor::init() {
instance_ = new MapEditor();
}
void MapEditor::destroy() {
delete instance_;
instance_ = nullptr;
}
auto MapEditor::get() -> MapEditor* {
return instance_;
}
// Constructor
MapEditor::MapEditor() = default;
// Destructor
MapEditor::~MapEditor() = default;
// Entra en modo editor
void MapEditor::enter(std::shared_ptr<Room> room, std::shared_ptr<Player> player,
const std::string& room_path, std::shared_ptr<Scoreboard::Data> scoreboard_data) {
if (active_) { return; }
room_ = std::move(room);
player_ = std::move(player);
room_path_ = room_path;
scoreboard_data_ = std::move(scoreboard_data);
// Guardar estado de invencibilidad y forzarla
invincible_before_editor_ = Options::cheats.invincible;
Options::cheats.invincible = Options::Cheat::State::ENABLED;
player_->setColor();
// Crear la barra de estado
statusbar_ = std::make_unique<EditorStatusBar>(room_->getNumber(), room_->getName());
// Pausar enemigos e items
room_->setPaused(true);
active_ = true;
std::cout << "MapEditor: ON (room " << room_path_ << ")\n";
}
// Sale del modo editor
void MapEditor::exit() {
if (!active_) { return; }
active_ = false;
// Restaurar invencibilidad
Options::cheats.invincible = invincible_before_editor_;
player_->setColor();
// Despausar enemigos e items
room_->setPaused(false);
// Liberar recursos
statusbar_.reset();
room_.reset();
player_.reset();
scoreboard_data_.reset();
std::cout << "MapEditor: OFF\n";
}
// Actualiza el editor
void MapEditor::update([[maybe_unused]] float delta_time) {
// Mantener el ratón siempre visible
SDL_ShowCursor();
Mouse::last_mouse_move_time = SDL_GetTicks();
// Actualizar posición del ratón
updateMousePosition();
// Actualizar la barra de estado con las coordenadas del ratón
if (statusbar_) {
statusbar_->setMouseTile(mouse_tile_x_, mouse_tile_y_);
statusbar_->update(delta_time);
}
}
// Renderiza el editor
void MapEditor::render() {
// El tilemap ya ha sido renderizado por Game::renderPlaying() antes de llamar aquí
// Renderizar entidades (por ahora: enemigos, items, jugador normales)
room_->renderEnemies();
room_->renderItems();
player_->render();
// Renderizar barra de estado del editor (reemplaza al scoreboard)
if (statusbar_) {
statusbar_->render();
}
}
// Maneja eventos del editor
void MapEditor::handleEvent([[maybe_unused]] const SDL_Event& event) {
// Por ahora no procesamos eventos específicos del editor
// En fases posteriores: drag & drop
}
// Convierte coordenadas de ventana a coordenadas de juego y tile
void MapEditor::updateMousePosition() {
float mouse_x = 0.0F;
float mouse_y = 0.0F;
SDL_GetMouseState(&mouse_x, &mouse_y);
float render_x = 0.0F;
float render_y = 0.0F;
SDL_RenderCoordinatesFromWindow(Screen::get()->getRenderer(), mouse_x, mouse_y, &render_x, &render_y);
SDL_FRect dst_rect = Screen::get()->getGameSurfaceDstRect();
mouse_game_x_ = render_x - dst_rect.x;
mouse_game_y_ = render_y - dst_rect.y;
// Convertir a coordenadas de tile (clampeadas al área de juego)
mouse_tile_x_ = static_cast<int>(mouse_game_x_) / Tile::SIZE;
mouse_tile_y_ = static_cast<int>(mouse_game_y_) / Tile::SIZE;
// Clampear a los límites del mapa
if (mouse_tile_x_ < 0) { mouse_tile_x_ = 0; }
if (mouse_tile_x_ >= PlayArea::WIDTH / Tile::SIZE) { mouse_tile_x_ = PlayArea::WIDTH / Tile::SIZE - 1; }
if (mouse_tile_y_ < 0) { mouse_tile_y_ = 0; }
if (mouse_tile_y_ >= PlayArea::HEIGHT / Tile::SIZE) { mouse_tile_y_ = PlayArea::HEIGHT / Tile::SIZE - 1; }
}
#endif // _DEBUG

View File

@@ -0,0 +1,68 @@
#pragma once
#ifdef _DEBUG
#include <SDL3/SDL.h>
#include <memory> // Para shared_ptr, unique_ptr
#include <string> // Para string
#include "game/entities/enemy.hpp" // Para Enemy::Data
#include "game/entities/item.hpp" // Para Item::Data
#include "game/entities/player.hpp" // Para Player::SpawnData
#include "game/gameplay/room.hpp" // Para Room::Data
#include "game/gameplay/scoreboard.hpp" // Para Scoreboard::Data
#include "game/options.hpp" // Para Options::Cheat
class EditorStatusBar;
class MapEditor {
public:
static void init(); // [SINGLETON] Crea el objeto
static void destroy(); // [SINGLETON] Destruye el objeto
static auto get() -> MapEditor*; // [SINGLETON] Obtiene el objeto
void enter(std::shared_ptr<Room> room, std::shared_ptr<Player> player,
const std::string& room_path, std::shared_ptr<Scoreboard::Data> scoreboard_data);
void exit();
[[nodiscard]] auto isActive() const -> bool { return active_; }
void update(float delta_time);
void render();
void handleEvent(const SDL_Event& event);
private:
static MapEditor* instance_; // [SINGLETON] Objeto privado
MapEditor(); // Constructor
~MapEditor(); // Destructor
void updateMousePosition(); // Convierte coordenadas de ventana a coordenadas de juego y tile
// Estado del editor
bool active_{false};
// Copia mutable de los datos de la habitación (para edición futura)
Room::Data room_data_;
Player::SpawnData player_spawn_;
std::string room_path_;
// Referencias a objetos vivos (para rendering)
std::shared_ptr<Room> room_;
std::shared_ptr<Player> player_;
std::shared_ptr<Scoreboard::Data> scoreboard_data_;
// Barra de estado del editor
std::unique_ptr<EditorStatusBar> statusbar_;
// Estado del ratón en coordenadas de juego
float mouse_game_x_{0.0F};
float mouse_game_y_{0.0F};
int mouse_tile_x_{0};
int mouse_tile_y_{0};
// Estado previo de invencibilidad (para restaurar al salir)
Options::Cheat::State invincible_before_editor_{Options::Cheat::State::DISABLED};
};
#endif // _DEBUG