migrades portes i plataformes a solidActor

This commit is contained in:
2026-04-11 12:54:54 +02:00
parent 49f6ed41e6
commit 5b2f986d32
22 changed files with 686 additions and 286 deletions

View File

@@ -2,32 +2,31 @@
#include <utility> // Para std::move
#include "game/entities/door.hpp" // Para Door
#include "game/gameplay/collision_map.hpp" // Para CollisionMap
#include "game/gameplay/door_tracker.hpp" // Para DoorTracker
#include "game/gameplay/inventory.hpp" // Para Inventory
#include "game/gameplay/tile_collider.hpp" // Para TileCollider::Tile
#include "utils/defines.hpp" // Para Map::WIDTH, Tile::SIZE
#include "utils/utils.hpp" // Para checkCollision
#include "game/entities/door.hpp" // Para Door
#include "game/gameplay/door_tracker.hpp" // Para DoorTracker
#include "game/gameplay/inventory.hpp" // Para Inventory
#include "game/gameplay/solid_actor_manager.hpp" // Para SolidActorManager
#include "utils/utils.hpp" // Para checkCollision
// Constructor
DoorManager::DoorManager(std::string room_id, CollisionMap* collision_map)
DoorManager::DoorManager(std::string room_id, SolidActorManager* solid_actors)
: room_id_(std::move(room_id)),
collision_map_(collision_map) {
solid_actors_(solid_actors) {
}
// Añade una puerta. Si está bloqueante (CLOSED), pinta sus 4 tiles como WALL
// en el CollisionMap. Si ya está OPENED (porque venía persistida del
// DoorTracker), no se tocan los tiles.
// Añade una puerta y la registra en el SolidActorManager. El bit
// BLOCKS_PLAYER del propio Door determina si bloquea al Player (se setea en
// el constructor si la puerta no arranca ya abierta desde el DoorTracker).
void DoorManager::addDoor(std::shared_ptr<Door> door) { // NOLINT(readability-identifier-naming)
if (door->isBlocking()) {
writeDoorTiles(*door, static_cast<int>(TileCollider::Tile::WALL));
}
solid_actors_->registerActor(door.get());
doors_.push_back(std::move(door));
}
// Elimina todas las puertas
// Elimina todas las puertas y las desregistra del SolidActorManager
void DoorManager::clear() {
for (const auto& door : doors_) {
solid_actors_->unregisterActor(door.get());
}
doors_.clear();
}
@@ -36,9 +35,10 @@ void DoorManager::update(float delta_time) {
for (const auto& door : doors_) {
door->update(delta_time);
// Si la puerta acaba de transicionar a OPENED, liberar los tiles y persistir
// Si la puerta acaba de transicionar a OPENED, persistir en DoorTracker.
// El flag BLOCKS_PLAYER ya se limpió dentro de Door::update(), así que
// el sweep del SolidActorManager deja de verla como muro automáticamente.
if (door->justOpened()) {
writeDoorTiles(*door, static_cast<int>(TileCollider::Tile::EMPTY));
DoorTracker::get()->addDoor(room_id_, door->getPos());
}
}
@@ -79,48 +79,17 @@ void DoorManager::tryUnlock(const SDL_FRect& player_rect) {
}
#ifdef _DEBUG
// Mueve una puerta del editor: limpia los WALLs viejos, reposiciona el sprite,
// y reescribe los WALLs nuevos si la puerta sigue siendo bloqueante.
// Mueve una puerta del editor: reposiciona su sprite y AABB. El registro
// en el SolidActorManager se mantiene (el manager lee el AABB actual).
void DoorManager::moveDoor(int index, float x, float y) {
if (index < 0 || index >= static_cast<int>(doors_.size())) { return; }
auto& door = doors_[index];
// Limpiar los WALLs viejos antes de mover
if (door->isBlocking()) {
writeDoorTiles(*door, static_cast<int>(TileCollider::Tile::EMPTY));
}
// Reposicionar el sprite y el collider del Door
door->setPosition(x, y);
// Re-escribir los WALLs nuevos en la nueva posición si sigue siendo bloqueante
if (door->isBlocking()) {
writeDoorTiles(*door, static_cast<int>(TileCollider::Tile::WALL));
}
doors_[index]->setPosition(x, y);
}
// Elimina una puerta del editor, limpiando los WALLs antes de borrarla del vector
// Elimina una puerta del editor, desregistrándola del SolidActorManager
void DoorManager::removeDoor(int index) {
if (index < 0 || index >= static_cast<int>(doors_.size())) { return; }
auto& door = doors_[index];
if (door->isBlocking()) {
writeDoorTiles(*door, static_cast<int>(TileCollider::Tile::EMPTY));
}
solid_actors_->unregisterActor(doors_[index].get());
doors_.erase(doors_.begin() + index);
}
#endif
// Setea las 4 celdas que ocupa la puerta (1 col × 4 filas) al valor indicado
void DoorManager::writeDoorTiles(const Door& door, int tile_value) {
// Convertir posición en píxeles a coordenadas de tile
const SDL_FPoint POS = door.getPos();
const int COL = static_cast<int>(POS.x) / Tile::SIZE;
const int ROW = static_cast<int>(POS.y) / Tile::SIZE;
for (int i = 0; i < DOOR_TILES_HEIGHT; ++i) {
const int INDEX = ((ROW + i) * Map::WIDTH) + COL;
collision_map_->setCollisionTile(INDEX, tile_value);
}
}