diff --git a/source/core/rendering/sprite/animated_sprite.hpp b/source/core/rendering/sprite/animated_sprite.hpp index f320816..1877261 100644 --- a/source/core/rendering/sprite/animated_sprite.hpp +++ b/source/core/rendering/sprite/animated_sprite.hpp @@ -47,14 +47,12 @@ class AnimatedSprite : public MovingSprite { void setCurrentAnimation(int index = 0); // Establece la animación actual por índice void resetAnimation(); // Reinicia la animación void setCurrentAnimationFrame(int num); // Establece el frame actual de la animación + void animate(float delta_time); // Calcula el frame correspondiente a la animación actual (time-based) protected: // Constructor per a ús de subclasses que gestionen la surface directament (sense YAML) AnimatedSprite(std::shared_ptr surface, SDL_FRect pos); - // Métodos protegidos - void animate(float delta_time); // Calcula el frame correspondiente a la animación actual (time-based) - private: // Variables miembro std::vector animations_; // Vector con las diferentes animaciones diff --git a/source/game/editor/map_editor.cpp b/source/game/editor/map_editor.cpp index 793c1e9..fa51839 100644 --- a/source/game/editor/map_editor.cpp +++ b/source/game/editor/map_editor.cpp @@ -8,11 +8,14 @@ #include "core/input/mouse.hpp" // Para Mouse #include "core/rendering/screen.hpp" // Para Screen +#include "core/rendering/surface.hpp" // Para Surface +#include "core/resources/resource_cache.hpp" // Para Resource::Cache #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 +#include "utils/utils.hpp" // Para stringToColor // Singleton MapEditor* MapEditor::instance_ = nullptr; @@ -46,6 +49,12 @@ void MapEditor::enter(std::shared_ptr room, std::shared_ptr player room_path_ = room_path; scoreboard_data_ = std::move(scoreboard_data); + // Cargar una copia de los datos de la habitación (para boundaries y edición futura) + auto room_data_ptr = Resource::Cache::get()->getRoom(room_path); + if (room_data_ptr) { + room_data_ = *room_data_ptr; + } + // Guardar estado de invencibilidad y forzarla invincible_before_editor_ = Options::cheats.invincible; Options::cheats.invincible = Options::Cheat::State::ENABLED; @@ -54,9 +63,6 @@ void MapEditor::enter(std::shared_ptr room, std::shared_ptr player // Crear la barra de estado statusbar_ = std::make_unique(room_->getNumber(), room_->getName()); - // Pausar enemigos e items - room_->setPaused(true); - active_ = true; std::cout << "MapEditor: ON (room " << room_path_ << ")\n"; } @@ -71,9 +77,6 @@ void MapEditor::exit() { Options::cheats.invincible = invincible_before_editor_; player_->setColor(); - // Despausar enemigos e items - room_->setPaused(false); - // Liberar recursos statusbar_.reset(); room_.reset(); @@ -84,11 +87,14 @@ void MapEditor::exit() { } // Actualiza el editor -void MapEditor::update([[maybe_unused]] float delta_time) { +void MapEditor::update(float delta_time) { // Mantener el ratón siempre visible SDL_ShowCursor(); Mouse::last_mouse_move_time = SDL_GetTicks(); + // Actualizar animaciones de enemigos e items (sin mover enemigos) + room_->updateEditorMode(delta_time); + // Actualizar posición del ratón updateMousePosition(); @@ -102,7 +108,11 @@ void MapEditor::update([[maybe_unused]] float 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) + + // Renderizar los marcadores de boundaries y líneas de ruta (debajo de los sprites) + renderEnemyBoundaries(); + + // Renderizar entidades normales: enemigos (animados en posición inicial), items, jugador room_->renderEnemies(); room_->renderItems(); player_->render(); @@ -119,6 +129,48 @@ void MapEditor::handleEvent([[maybe_unused]] const SDL_Event& event) { // En fases posteriores: drag & drop } +// Dibuja marcadores de boundaries y líneas de ruta para los enemigos +void MapEditor::renderEnemyBoundaries() { + auto game_surface = Screen::get()->getRendererSurface(); + if (!game_surface) { return; } + + const Uint8 COLOR_BOUND1 = stringToColor("bright_cyan"); + const Uint8 COLOR_BOUND2 = stringToColor("bright_yellow"); + const Uint8 COLOR_ROUTE = stringToColor("bright_white"); + + for (const auto& enemy : room_data_.enemies) { + // Dibujar línea de ruta: boundary1 → posición inicial → boundary2 + // Usamos el centro del tile como punto de referencia para las líneas + constexpr float HALF = Tile::SIZE / 2.0F; + + float init_cx = enemy.x + HALF; + float init_cy = enemy.y + HALF; + float b1_cx = static_cast(enemy.x1) + HALF; + float b1_cy = static_cast(enemy.y1) + HALF; + float b2_cx = static_cast(enemy.x2) + HALF; + float b2_cy = static_cast(enemy.y2) + HALF; + + // Línea de boundary1 a posición inicial + game_surface->drawLine(b1_cx, b1_cy, init_cx, init_cy, COLOR_ROUTE); + // Línea de posición inicial a boundary2 + game_surface->drawLine(init_cx, init_cy, b2_cx, b2_cy, COLOR_ROUTE); + + // Marcadores en las boundaries + renderBoundaryMarker(static_cast(enemy.x1), static_cast(enemy.y1), COLOR_BOUND1); + renderBoundaryMarker(static_cast(enemy.x2), static_cast(enemy.y2), COLOR_BOUND2); + } +} + +// Dibuja un marcador de boundary (rectángulo pequeño) en una posición +void MapEditor::renderBoundaryMarker(float x, float y, Uint8 color) { + auto game_surface = Screen::get()->getRendererSurface(); + if (!game_surface) { return; } + + // Dibujar un rectángulo de 8x8 como marcador + SDL_FRect marker = {.x = x, .y = y, .w = static_cast(Tile::SIZE), .h = static_cast(Tile::SIZE)}; + game_surface->drawRectBorder(&marker, color); +} + // Convierte coordenadas de ventana a coordenadas de juego y tile void MapEditor::updateMousePosition() { float mouse_x = 0.0F; diff --git a/source/game/editor/map_editor.hpp b/source/game/editor/map_editor.hpp index 01dbcb1..23dfccd 100644 --- a/source/game/editor/map_editor.hpp +++ b/source/game/editor/map_editor.hpp @@ -37,7 +37,9 @@ class MapEditor { MapEditor(); // Constructor ~MapEditor(); // Destructor - void updateMousePosition(); // Convierte coordenadas de ventana a coordenadas de juego y tile + void updateMousePosition(); // Convierte coordenadas de ventana a coordenadas de juego y tile + void renderEnemyBoundaries(); // Dibuja marcadores de boundaries y líneas de ruta + void renderBoundaryMarker(float x, float y, Uint8 color); // Dibuja un marcador de boundary en una posición // Estado del editor bool active_{false}; diff --git a/source/game/entities/enemy.cpp b/source/game/entities/enemy.cpp index 23bb0c6..2deef6a 100644 --- a/source/game/entities/enemy.cpp +++ b/source/game/entities/enemy.cpp @@ -48,6 +48,13 @@ void Enemy::update(float delta_time) { collider_ = getRect(); } +#ifdef _DEBUG +// Solo actualiza la animación sin mover al enemigo +void Enemy::updateAnimation(float delta_time) { + sprite_->animate(delta_time); +} +#endif + // Comprueba si ha llegado al limite del recorrido para darse media vuelta void Enemy::checkPath() { // NOLINT(readability-make-member-function-const) if (sprite_->getPosX() > x2_ || sprite_->getPosX() < x1_) { diff --git a/source/game/entities/enemy.hpp b/source/game/entities/enemy.hpp index 02d23f4..34ff91f 100644 --- a/source/game/entities/enemy.hpp +++ b/source/game/entities/enemy.hpp @@ -29,6 +29,9 @@ class Enemy { void render(); // Pinta el enemigo en pantalla void update(float delta_time); // Actualiza las variables del objeto +#ifdef _DEBUG + void updateAnimation(float delta_time); // Solo actualiza la animación sin mover al enemigo +#endif auto getRect() -> SDL_FRect; // Devuelve el rectangulo que contiene al enemigo auto getCollider() -> SDL_FRect&; // Obtiene el rectangulo de colision del enemigo diff --git a/source/game/gameplay/enemy_manager.cpp b/source/game/gameplay/enemy_manager.cpp index 2f1c6b3..d4e1b8b 100644 --- a/source/game/gameplay/enemy_manager.cpp +++ b/source/game/gameplay/enemy_manager.cpp @@ -41,6 +41,15 @@ void EnemyManager::render() { } } +#ifdef _DEBUG +// Solo actualiza animaciones sin mover enemigos +void EnemyManager::updateAnimations(float delta_time) { + for (const auto& enemy : enemies_) { + enemy->updateAnimation(delta_time); + } +} +#endif + // Comprueba si hay colisión con algún enemigo auto EnemyManager::checkCollision(SDL_FRect& rect) -> bool { return std::ranges::any_of(enemies_, [&rect](const auto& enemy) { diff --git a/source/game/gameplay/enemy_manager.hpp b/source/game/gameplay/enemy_manager.hpp index cba3c5b..f4b2bc7 100644 --- a/source/game/gameplay/enemy_manager.hpp +++ b/source/game/gameplay/enemy_manager.hpp @@ -40,6 +40,10 @@ class EnemyManager { // Detección de colisiones auto checkCollision(SDL_FRect& rect) -> bool; // Comprueba si hay colisión con algún enemigo +#ifdef _DEBUG + void updateAnimations(float delta_time); // Solo actualiza animaciones sin mover enemigos +#endif + private: std::vector> enemies_; // Colección de enemigos }; diff --git a/source/game/gameplay/room.cpp b/source/game/gameplay/room.cpp index 57ca566..1e52e12 100644 --- a/source/game/gameplay/room.cpp +++ b/source/game/gameplay/room.cpp @@ -121,6 +121,13 @@ void Room::renderItems() { void Room::redrawMap() { tilemap_renderer_->redrawMap(collision_map_.get()); } + +// Actualiza animaciones sin mover enemigos (para editor de mapas) +void Room::updateEditorMode(float delta_time) { + tilemap_renderer_->update(delta_time); + enemy_manager_->updateAnimations(delta_time); + item_manager_->update(delta_time); +} #endif // Actualiza las variables y objetos de la habitación diff --git a/source/game/gameplay/room.hpp b/source/game/gameplay/room.hpp index c05a49f..241adbb 100644 --- a/source/game/gameplay/room.hpp +++ b/source/game/gameplay/room.hpp @@ -69,7 +69,8 @@ class Room { void renderEnemies(); // Dibuja los enemigos en pantalla void renderItems(); // Dibuja los objetos en pantalla #ifdef _DEBUG - void redrawMap(); // Redibuja el mapa (para actualizar modo debug) + void redrawMap(); // Redibuja el mapa (para actualizar modo debug) + void updateEditorMode(float delta_time); // Actualiza animaciones sin mover enemigos (para editor) #endif void update(float delta_time); // Actualiza las variables y objetos de la habitación auto getRoom(Border border) -> std::string; // Devuelve la cadena del fichero de la habitación contigua segun el borde