84 lines
2.8 KiB
C++
84 lines
2.8 KiB
C++
#include "game/entities/door.hpp"
|
|
|
|
#include "core/rendering/sprite/animated_sprite.hpp" // Para AnimatedSprite
|
|
#include "core/resources/resource_cache.hpp" // Para Resource
|
|
|
|
// Constructor: carga la animación y posiciona la puerta. Si start_opened es
|
|
// true, la puerta se crea ya abierta (estado OPENED, animación "opened"); en
|
|
// caso contrario, se crea cerrada (estado CLOSED, animación "closed") y
|
|
// activa el flag BLOCKS_PLAYER del SolidActor para que los sweeps del
|
|
// SolidActorManager la vean como muro.
|
|
Door::Door(const Data& data, bool start_opened)
|
|
: sprite_(std::make_shared<AnimatedSprite>(Resource::Cache::get()->getAnimationData(data.animation_path))),
|
|
id_(data.id),
|
|
state_(start_opened ? State::OPENED : State::CLOSED) {
|
|
sprite_->setPosX(data.x);
|
|
sprite_->setPosY(data.y);
|
|
sprite_->setCurrentAnimation(start_opened ? "opened" : "closed");
|
|
aabb_ = sprite_->getRect();
|
|
if (!start_opened) {
|
|
flags_ = BLOCKS_PLAYER;
|
|
}
|
|
}
|
|
|
|
// Pinta la puerta en pantalla
|
|
void Door::render() {
|
|
sprite_->render();
|
|
}
|
|
|
|
// Avanza la animación. Solo OPENING anima de verdad; CLOSED y OPENED son
|
|
// frames estáticos. Cuando la animación de OPENING termina, transiciona a
|
|
// OPENED, fija el frame final, limpia el flag BLOCKS_PLAYER (los sweeps
|
|
// del SolidActorManager dejan de verla como muro) y marca just_opened_
|
|
// para que el DoorManager persista el estado abierto en DoorTracker.
|
|
void Door::update(float delta_time) {
|
|
if (is_paused_) {
|
|
return;
|
|
}
|
|
|
|
if (state_ == State::OPENING) {
|
|
sprite_->animate(delta_time);
|
|
if (sprite_->animationIsCompleted()) {
|
|
state_ = State::OPENED;
|
|
sprite_->setCurrentAnimation("opened");
|
|
flags_ = 0; // Deja de bloquear al Player
|
|
just_opened_ = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Posición actual (para registrar el estado abierto en DoorTracker)
|
|
auto Door::getPos() const -> SDL_FPoint {
|
|
return SDL_FPoint{.x = sprite_->getX(), .y = sprite_->getY()};
|
|
}
|
|
|
|
// Transición CLOSED → OPENING: cambia el estado y arranca la animación de apertura
|
|
void Door::startOpening() {
|
|
if (state_ != State::CLOSED) {
|
|
return;
|
|
}
|
|
state_ = State::OPENING;
|
|
sprite_->setCurrentAnimation("opening");
|
|
sprite_->resetAnimation();
|
|
}
|
|
|
|
// Flag one-shot: devuelve true exactamente una vez después de transicionar a OPENED
|
|
auto Door::justOpened() -> bool {
|
|
if (just_opened_) {
|
|
just_opened_ = false;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
// Mueve la puerta a la posición indicada (sprite + AABB del SolidActor).
|
|
// Usado por el editor; el DoorManager::moveDoor se encarga del bookkeeping
|
|
// de registro en el SolidActorManager.
|
|
void Door::setPosition(float x, float y) {
|
|
sprite_->setPosX(x);
|
|
sprite_->setPosY(y);
|
|
aabb_ = sprite_->getRect();
|
|
}
|
|
#endif
|