treballant en sistema de portes i claus
This commit is contained in:
65
source/game/entities/door.cpp
Normal file
65
source/game/entities/door.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#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").
|
||||
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");
|
||||
collider_ = sprite_->getRect();
|
||||
}
|
||||
|
||||
// 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 y marca just_opened_ para que el DoorManager
|
||||
// libere los tiles de colisión.
|
||||
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");
|
||||
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;
|
||||
}
|
||||
62
source/game/entities/door.hpp
Normal file
62
source/game/entities/door.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <memory> // Para shared_ptr
|
||||
#include <string> // Para string
|
||||
|
||||
class AnimatedSprite;
|
||||
|
||||
/**
|
||||
* @brief Puerta que actúa como muro hasta que se abre con la llave correcta
|
||||
*
|
||||
* Entidad de 8x32 px (1 columna × 4 filas de tiles) con tres animaciones:
|
||||
* - "closed": estado inicial bloqueante (frame estático)
|
||||
* - "opening": animación de transición que se reproduce una sola vez
|
||||
* - "opened": estado final no bloqueante (frame estático)
|
||||
*
|
||||
* El comportamiento de "muro" se implementa marcando los 4 tiles que ocupa
|
||||
* la puerta como WALL en el CollisionMap (lo gestiona el DoorManager). Cuando
|
||||
* la puerta termina de abrirse, los tiles vuelven a EMPTY y el jugador puede
|
||||
* pasar.
|
||||
*/
|
||||
class Door {
|
||||
public:
|
||||
enum class State : int {
|
||||
CLOSED = 0,
|
||||
OPENING = 1,
|
||||
OPENED = 2
|
||||
};
|
||||
|
||||
struct Data {
|
||||
std::string animation_path; // Ruta al fichero de animación (ej. "door1.yaml")
|
||||
std::string id; // Identificador que coincide con el id de la llave que la abre
|
||||
float x{0.0F}; // Posición X en píxeles (alineada al grid de 8 px)
|
||||
float y{0.0F}; // Posición Y en píxeles (alineada al grid de 8 px)
|
||||
};
|
||||
|
||||
explicit Door(const Data& data, bool start_opened);
|
||||
~Door() = default;
|
||||
|
||||
void render(); // Pinta la puerta en pantalla
|
||||
void update(float delta_time); // Avanza la animación; si OPENING termina → OPENED
|
||||
|
||||
auto getCollider() -> SDL_FRect& { return collider_; } // Rectángulo de colisión (8x32)
|
||||
[[nodiscard]] auto getPos() const -> SDL_FPoint; // Posición en píxeles
|
||||
[[nodiscard]] auto getId() const -> const std::string& { return id_; } // Identificador
|
||||
[[nodiscard]] auto getState() const -> State { return state_; } // Estado actual
|
||||
[[nodiscard]] auto isBlocking() const -> bool { return state_ != State::OPENED; } // True si bloquea al jugador
|
||||
|
||||
void startOpening(); // Transición CLOSED → OPENING
|
||||
auto justOpened() -> bool; // Flag one-shot consumido por el manager
|
||||
|
||||
void setPaused(bool paused) { is_paused_ = paused; } // Pausa/despausa la animación
|
||||
|
||||
private:
|
||||
std::shared_ptr<AnimatedSprite> sprite_; // Sprite animado de la puerta
|
||||
SDL_FRect collider_{}; // Rectángulo de colisión
|
||||
std::string id_; // Identificador
|
||||
State state_{State::CLOSED}; // Estado actual
|
||||
bool just_opened_{false}; // Flag one-shot: la puerta acaba de transicionar a OPENED
|
||||
bool is_paused_{false}; // Indica si la puerta está pausada
|
||||
};
|
||||
32
source/game/entities/key.cpp
Normal file
32
source/game/entities/key.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "game/entities/key.hpp"
|
||||
|
||||
#include "core/rendering/sprite/animated_sprite.hpp" // Para AnimatedSprite
|
||||
#include "core/resources/resource_cache.hpp" // Para Resource
|
||||
|
||||
// Constructor: carga la animación, posiciona el sprite y crea el collider
|
||||
Key::Key(const Data& data)
|
||||
: sprite_(std::make_shared<AnimatedSprite>(Resource::Cache::get()->getAnimationData(data.animation_path))),
|
||||
id_(data.id) {
|
||||
sprite_->setPosX(data.x);
|
||||
sprite_->setPosY(data.y);
|
||||
sprite_->setCurrentAnimation("default");
|
||||
collider_ = sprite_->getRect();
|
||||
}
|
||||
|
||||
// Pinta la llave en pantalla
|
||||
void Key::render() {
|
||||
sprite_->render();
|
||||
}
|
||||
|
||||
// Avanza la animación de la llave
|
||||
void Key::update(float delta_time) {
|
||||
if (is_paused_) {
|
||||
return;
|
||||
}
|
||||
sprite_->animate(delta_time);
|
||||
}
|
||||
|
||||
// Posición actual (para registrar pickup en KeyTracker)
|
||||
auto Key::getPos() const -> SDL_FPoint {
|
||||
return SDL_FPoint{.x = sprite_->getX(), .y = sprite_->getY()};
|
||||
}
|
||||
44
source/game/entities/key.hpp
Normal file
44
source/game/entities/key.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <memory> // Para shared_ptr
|
||||
#include <string> // Para string
|
||||
|
||||
class AnimatedSprite;
|
||||
|
||||
/**
|
||||
* @brief Llave coleccionable
|
||||
*
|
||||
* Entidad de 16x16 px con una animación "default". Al ser recogida por el
|
||||
* jugador, su identificador (id_) se añade al Inventory global y la llave
|
||||
* desaparece de la habitación. Una llave puede abrir todas las puertas con
|
||||
* el mismo id; no se consume al usarse.
|
||||
*/
|
||||
class Key {
|
||||
public:
|
||||
struct Data {
|
||||
std::string animation_path; // Ruta al fichero de animación (ej. "key1.yaml")
|
||||
std::string id; // Identificador que abre las puertas con el mismo id
|
||||
float x{0.0F}; // Posición X en píxeles
|
||||
float y{0.0F}; // Posición Y en píxeles
|
||||
};
|
||||
|
||||
explicit Key(const Data& data);
|
||||
~Key() = default;
|
||||
|
||||
void render(); // Pinta la llave en pantalla
|
||||
void update(float delta_time); // Avanza la animación
|
||||
|
||||
auto getCollider() -> SDL_FRect& { return collider_; } // Rectángulo de colisión
|
||||
[[nodiscard]] auto getPos() const -> SDL_FPoint; // Posición actual (para tracker)
|
||||
[[nodiscard]] auto getId() const -> const std::string& { return id_; } // Identificador de la llave
|
||||
|
||||
void setPaused(bool paused) { is_paused_ = paused; } // Pausa/despausa la animación
|
||||
|
||||
private:
|
||||
std::shared_ptr<AnimatedSprite> sprite_; // Sprite animado de la llave
|
||||
SDL_FRect collider_{}; // Rectángulo de colisión
|
||||
std::string id_; // Identificador
|
||||
bool is_paused_{false}; // Indica si la llave está pausada
|
||||
};
|
||||
@@ -10,13 +10,14 @@ class AnimatedSprite;
|
||||
|
||||
// Punto de paso en la ruta de una plataforma
|
||||
struct Waypoint {
|
||||
float x{0.0F}; // Posición en pixels
|
||||
float x{0.0F}; // Posición en pixels
|
||||
float y{0.0F};
|
||||
float wait{0.0F}; // Tiempo de parada en este punto (segundos, 0 = sin parada)
|
||||
};
|
||||
|
||||
// Modo de recorrido de la ruta
|
||||
enum class LoopMode { PINGPONG, CIRCULAR };
|
||||
enum class LoopMode { PINGPONG,
|
||||
CIRCULAR };
|
||||
|
||||
// Tipo de función de easing
|
||||
using EasingFunc = float (*)(float);
|
||||
@@ -25,11 +26,11 @@ class MovingPlatform {
|
||||
public:
|
||||
struct Data {
|
||||
std::string animation_path;
|
||||
float speed{30.0F}; // px/s a lo largo del path
|
||||
float speed{30.0F}; // px/s a lo largo del path
|
||||
LoopMode loop{LoopMode::PINGPONG};
|
||||
std::string easing{"linear"}; // Nombre del easing
|
||||
int frame{0}; // Frame inicial (-1 = random)
|
||||
std::vector<Waypoint> path; // Mínimo 2 puntos
|
||||
std::string easing{"linear"}; // Nombre del easing
|
||||
int frame{0}; // Frame inicial (-1 = random)
|
||||
std::vector<Waypoint> path; // Mínimo 2 puntos
|
||||
};
|
||||
|
||||
explicit MovingPlatform(const Data& data);
|
||||
|
||||
Reference in New Issue
Block a user