Compare commits
6 Commits
metal-inte
...
19768cb72b
| Author | SHA1 | Date | |
|---|---|---|---|
| 19768cb72b | |||
| 26e0fd7247 | |||
| e2fd470ad3 | |||
| a72ae0a5fc | |||
| 7579594c22 | |||
| 6c702e7e23 |
9
.claude/settings.local.json
Normal file
9
.claude/settings.local.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"permissions": {
|
||||||
|
"allow": [
|
||||||
|
"Bash(make:*)"
|
||||||
|
],
|
||||||
|
"deny": [],
|
||||||
|
"ask": []
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,6 +43,10 @@ auto loadAnimationsFromFile(const std::string& file_path) -> AnimationsFileBuffe
|
|||||||
std::vector<std::string> buffer;
|
std::vector<std::string> buffer;
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(input_stream, line)) {
|
while (std::getline(input_stream, line)) {
|
||||||
|
// Eliminar caracteres de retorno de carro (\r) al final de la línea
|
||||||
|
if (!line.empty() && line.back() == '\r') {
|
||||||
|
line.pop_back();
|
||||||
|
}
|
||||||
if (!line.empty()) {
|
if (!line.empty()) {
|
||||||
buffer.push_back(line);
|
buffer.push_back(line);
|
||||||
}
|
}
|
||||||
@@ -82,7 +86,7 @@ auto AnimatedSprite::getAnimationIndex(const std::string& name) -> int {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calcula el frame correspondiente a la animación
|
// Calcula el frame correspondiente a la animación (frame-based)
|
||||||
void AnimatedSprite::animate() {
|
void AnimatedSprite::animate() {
|
||||||
if (animations_[current_animation_].speed == 0 || animations_[current_animation_].paused) {
|
if (animations_[current_animation_].speed == 0 || animations_[current_animation_].paused) {
|
||||||
return;
|
return;
|
||||||
@@ -112,6 +116,39 @@ void AnimatedSprite::animate() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calcula el frame correspondiente a la animación (time-based)
|
||||||
|
void AnimatedSprite::animate(float deltaTime) {
|
||||||
|
if (animations_[current_animation_].speed == 0 || animations_[current_animation_].paused) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convertir speed (frames) a tiempo: speed frames = speed/60 segundos a 60fps
|
||||||
|
float frameTime = static_cast<float>(animations_[current_animation_].speed) / 60.0f;
|
||||||
|
|
||||||
|
// Acumular tiempo transcurrido
|
||||||
|
animations_[current_animation_].time_accumulator += deltaTime;
|
||||||
|
|
||||||
|
// Verificar si es momento de cambiar frame
|
||||||
|
if (animations_[current_animation_].time_accumulator >= frameTime) {
|
||||||
|
animations_[current_animation_].time_accumulator -= frameTime;
|
||||||
|
animations_[current_animation_].current_frame++;
|
||||||
|
|
||||||
|
// Si alcanza el final de la animación
|
||||||
|
if (animations_[current_animation_].current_frame >= animations_[current_animation_].frames.size()) {
|
||||||
|
if (animations_[current_animation_].loop == -1) { // Si no hay loop, deja el último frame
|
||||||
|
animations_[current_animation_].current_frame = animations_[current_animation_].frames.size() - 1;
|
||||||
|
animations_[current_animation_].completed = true;
|
||||||
|
} else { // Si hay loop, vuelve al frame indicado
|
||||||
|
animations_[current_animation_].time_accumulator = 0.0f;
|
||||||
|
animations_[current_animation_].current_frame = animations_[current_animation_].loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actualizar el sprite clip
|
||||||
|
updateSpriteClip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Comprueba si ha terminado la animación
|
// Comprueba si ha terminado la animación
|
||||||
auto AnimatedSprite::animationIsCompleted() -> bool {
|
auto AnimatedSprite::animationIsCompleted() -> bool {
|
||||||
return animations_[current_animation_].completed;
|
return animations_[current_animation_].completed;
|
||||||
@@ -126,10 +163,12 @@ void AnimatedSprite::setCurrentAnimation(const std::string& name, bool reset) {
|
|||||||
if (reset) {
|
if (reset) {
|
||||||
animations_[current_animation_].current_frame = 0;
|
animations_[current_animation_].current_frame = 0;
|
||||||
animations_[current_animation_].counter = 0;
|
animations_[current_animation_].counter = 0;
|
||||||
|
animations_[current_animation_].time_accumulator = 0.0f;
|
||||||
animations_[current_animation_].completed = false;
|
animations_[current_animation_].completed = false;
|
||||||
} else {
|
} else {
|
||||||
animations_[current_animation_].current_frame = std::min(animations_[OLD_ANIMATION].current_frame, animations_[current_animation_].frames.size() - 1);
|
animations_[current_animation_].current_frame = std::min(animations_[OLD_ANIMATION].current_frame, animations_[current_animation_].frames.size() - 1);
|
||||||
animations_[current_animation_].counter = animations_[OLD_ANIMATION].counter;
|
animations_[current_animation_].counter = animations_[OLD_ANIMATION].counter;
|
||||||
|
animations_[current_animation_].time_accumulator = animations_[OLD_ANIMATION].time_accumulator;
|
||||||
animations_[current_animation_].completed = animations_[OLD_ANIMATION].completed;
|
animations_[current_animation_].completed = animations_[OLD_ANIMATION].completed;
|
||||||
}
|
}
|
||||||
updateSpriteClip();
|
updateSpriteClip();
|
||||||
@@ -145,26 +184,35 @@ void AnimatedSprite::setCurrentAnimation(int index, bool reset) {
|
|||||||
if (reset) {
|
if (reset) {
|
||||||
animations_[current_animation_].current_frame = 0;
|
animations_[current_animation_].current_frame = 0;
|
||||||
animations_[current_animation_].counter = 0;
|
animations_[current_animation_].counter = 0;
|
||||||
|
animations_[current_animation_].time_accumulator = 0.0f;
|
||||||
animations_[current_animation_].completed = false;
|
animations_[current_animation_].completed = false;
|
||||||
} else {
|
} else {
|
||||||
animations_[current_animation_].current_frame = std::min(animations_[OLD_ANIMATION].current_frame, animations_[current_animation_].frames.size());
|
animations_[current_animation_].current_frame = std::min(animations_[OLD_ANIMATION].current_frame, animations_[current_animation_].frames.size());
|
||||||
animations_[current_animation_].counter = animations_[OLD_ANIMATION].counter;
|
animations_[current_animation_].counter = animations_[OLD_ANIMATION].counter;
|
||||||
|
animations_[current_animation_].time_accumulator = animations_[OLD_ANIMATION].time_accumulator;
|
||||||
animations_[current_animation_].completed = animations_[OLD_ANIMATION].completed;
|
animations_[current_animation_].completed = animations_[OLD_ANIMATION].completed;
|
||||||
}
|
}
|
||||||
updateSpriteClip();
|
updateSpriteClip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza las variables del objeto
|
// Actualiza las variables del objeto (frame-based)
|
||||||
void AnimatedSprite::update() {
|
void AnimatedSprite::update() {
|
||||||
animate();
|
animate();
|
||||||
MovingSprite::update();
|
MovingSprite::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Actualiza las variables del objeto (time-based)
|
||||||
|
void AnimatedSprite::update(float deltaTime) {
|
||||||
|
animate(deltaTime);
|
||||||
|
MovingSprite::update(deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
// Reinicia la animación
|
// Reinicia la animación
|
||||||
void AnimatedSprite::resetAnimation() {
|
void AnimatedSprite::resetAnimation() {
|
||||||
animations_[current_animation_].current_frame = 0;
|
animations_[current_animation_].current_frame = 0;
|
||||||
animations_[current_animation_].counter = 0;
|
animations_[current_animation_].counter = 0;
|
||||||
|
animations_[current_animation_].time_accumulator = 0.0f;
|
||||||
animations_[current_animation_].completed = false;
|
animations_[current_animation_].completed = false;
|
||||||
animations_[current_animation_].paused = false;
|
animations_[current_animation_].paused = false;
|
||||||
updateSpriteClip();
|
updateSpriteClip();
|
||||||
|
|||||||
@@ -21,11 +21,12 @@ struct Animation {
|
|||||||
|
|
||||||
std::string name; // Nombre de la animación
|
std::string name; // Nombre de la animación
|
||||||
std::vector<SDL_FRect> frames; // Frames que componen la animación
|
std::vector<SDL_FRect> frames; // Frames que componen la animación
|
||||||
int speed{DEFAULT_SPEED}; // Velocidad de reproducción
|
int speed{DEFAULT_SPEED}; // Velocidad de reproducción (frame-based)
|
||||||
int loop{0}; // Frame de vuelta al terminar (-1 para no repetir)
|
int loop{0}; // Frame de vuelta al terminar (-1 para no repetir)
|
||||||
bool completed{false}; // Indica si la animación ha finalizado
|
bool completed{false}; // Indica si la animación ha finalizado
|
||||||
size_t current_frame{0}; // Frame actual en reproducción
|
size_t current_frame{0}; // Frame actual en reproducción
|
||||||
int counter{0}; // Contador para la animación
|
int counter{0}; // Contador para la animación (frame-based)
|
||||||
|
float time_accumulator{0.0f}; // Acumulador de tiempo para animaciones time-based
|
||||||
bool paused{false}; // La animación no avanza
|
bool paused{false}; // La animación no avanza
|
||||||
|
|
||||||
Animation() = default;
|
Animation() = default;
|
||||||
@@ -55,7 +56,8 @@ class AnimatedSprite : public MovingSprite {
|
|||||||
~AnimatedSprite() override = default;
|
~AnimatedSprite() override = default;
|
||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
void update() override; // Actualiza la animación
|
void update() override; // Actualiza la animación (frame-based)
|
||||||
|
void update(float deltaTime); // Actualiza la animación (time-based)
|
||||||
|
|
||||||
// --- Control de animaciones ---
|
// --- Control de animaciones ---
|
||||||
void setCurrentAnimation(const std::string& name = "default", bool reset = true); // Establece la animación por nombre
|
void setCurrentAnimation(const std::string& name = "default", bool reset = true); // Establece la animación por nombre
|
||||||
@@ -78,7 +80,8 @@ class AnimatedSprite : public MovingSprite {
|
|||||||
int current_animation_ = 0; // Índice de la animación activa
|
int current_animation_ = 0; // Índice de la animación activa
|
||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
void animate(); // Calcula el frame correspondiente a la animación
|
void animate(); // Calcula el frame correspondiente a la animación (frame-based)
|
||||||
|
void animate(float deltaTime); // Calcula el frame correspondiente a la animación (time-based)
|
||||||
void loadFromAnimationsFileBuffer(const AnimationsFileBuffer& source); // Carga la animación desde un vector de cadenas
|
void loadFromAnimationsFileBuffer(const AnimationsFileBuffer& source); // Carga la animación desde un vector de cadenas
|
||||||
void processConfigLine(const std::string& line, AnimationConfig& config); // Procesa una línea de configuración
|
void processConfigLine(const std::string& line, AnimationConfig& config); // Procesa una línea de configuración
|
||||||
void updateFrameCalculations(AnimationConfig& config); // Actualiza los cálculos basados en las dimensiones del frame
|
void updateFrameCalculations(AnimationConfig& config); // Actualiza los cálculos basados en las dimensiones del frame
|
||||||
|
|||||||
@@ -126,7 +126,14 @@ void Background::initializeTextures() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza la lógica del objeto
|
// Actualiza la lógica del objeto
|
||||||
|
// Actualiza la lógica del objeto (compatibilidad)
|
||||||
void Background::update() {
|
void Background::update() {
|
||||||
|
constexpr float FRAME_TIME_MS = 1000.0f / 60.0f; // 16.67ms por frame a 60 FPS
|
||||||
|
update(FRAME_TIME_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actualiza la lógica del objeto
|
||||||
|
void Background::update(float delta_time) {
|
||||||
// Actualiza la progresión y calcula transiciones
|
// Actualiza la progresión y calcula transiciones
|
||||||
if (!manual_mode_) {
|
if (!manual_mode_) {
|
||||||
updateProgression();
|
updateProgression();
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ class Background {
|
|||||||
~Background(); // Destructor
|
~Background(); // Destructor
|
||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
void update(); // Actualiza la lógica del objeto
|
void update(); // Actualiza la lógica del objeto (compatibilidad)
|
||||||
|
void update(float delta_time); // Actualiza la lógica del objeto
|
||||||
void render(); // Dibuja el objeto
|
void render(); // Dibuja el objeto
|
||||||
void reset(); // Reinicia la progresión
|
void reset(); // Reinicia la progresión
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ Director::Director(int argc, std::span<char *> argv) {
|
|||||||
Section::name = Section::Name::GAME;
|
Section::name = Section::Name::GAME;
|
||||||
Section::options = Section::Options::GAME_PLAY_1P;
|
Section::options = Section::Options::GAME_PLAY_1P;
|
||||||
#elif _DEBUG
|
#elif _DEBUG
|
||||||
Section::name = Section::Name::HI_SCORE_TABLE;
|
Section::name = Section::Name::INSTRUCTIONS;
|
||||||
Section::options = Section::Options::GAME_PLAY_1P;
|
Section::options = Section::Options::GAME_PLAY_1P;
|
||||||
#else // NORMAL GAME
|
#else // NORMAL GAME
|
||||||
Section::name = Section::Name::LOGO;
|
Section::name = Section::Name::LOGO;
|
||||||
|
|||||||
@@ -82,6 +82,11 @@ void Fade::update() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compatibilidad delta-time (ignora el parámetro ya que usa SDL_GetTicks)
|
||||||
|
void Fade::update(float delta_time) {
|
||||||
|
update(); // Llama al método original
|
||||||
|
}
|
||||||
|
|
||||||
void Fade::updatePreState() {
|
void Fade::updatePreState() {
|
||||||
// Sistema basado en tiempo únicamente
|
// Sistema basado en tiempo únicamente
|
||||||
Uint32 elapsed_time = SDL_GetTicks() - pre_start_time_;
|
Uint32 elapsed_time = SDL_GetTicks() - pre_start_time_;
|
||||||
|
|||||||
@@ -37,10 +37,11 @@ class Fade {
|
|||||||
~Fade();
|
~Fade();
|
||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
void reset(); // Resetea variables para reutilizar el fade
|
void reset(); // Resetea variables para reutilizar el fade
|
||||||
void render(); // Dibuja la transición en pantalla
|
void render(); // Dibuja la transición en pantalla
|
||||||
void update(); // Actualiza el estado interno
|
void update(); // Actualiza el estado interno (ya usa tiempo real)
|
||||||
void activate(); // Activa el fade
|
void update(float delta_time); // Compatibilidad delta-time (ignora el parámetro)
|
||||||
|
void activate(); // Activa el fade
|
||||||
|
|
||||||
// --- Configuración ---
|
// --- Configuración ---
|
||||||
void setColor(Uint8 r, Uint8 g, Uint8 b); // Establece el color RGB del fade
|
void setColor(Uint8 r, Uint8 g, Uint8 b); // Establece el color RGB del fade
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ void MovingSprite::stop() {
|
|||||||
flip_ = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite
|
flip_ = SDL_FLIP_NONE; // Establece como se ha de voltear el sprite
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mueve el sprite
|
// Mueve el sprite (frame-based)
|
||||||
void MovingSprite::move() {
|
void MovingSprite::move() {
|
||||||
x_ += vx_;
|
x_ += vx_;
|
||||||
y_ += vy_;
|
y_ += vy_;
|
||||||
@@ -65,16 +65,34 @@ void MovingSprite::move() {
|
|||||||
pos_.y = static_cast<int>(y_);
|
pos_.y = static_cast<int>(y_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza las variables internas del objeto
|
// Mueve el sprite (time-based)
|
||||||
|
void MovingSprite::move(float deltaTime) {
|
||||||
|
x_ += vx_ * deltaTime;
|
||||||
|
y_ += vy_ * deltaTime;
|
||||||
|
|
||||||
|
vx_ += ax_ * deltaTime;
|
||||||
|
vy_ += ay_ * deltaTime;
|
||||||
|
|
||||||
|
pos_.x = static_cast<int>(x_);
|
||||||
|
pos_.y = static_cast<int>(y_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actualiza las variables internas del objeto (frame-based)
|
||||||
void MovingSprite::update() {
|
void MovingSprite::update() {
|
||||||
move();
|
move();
|
||||||
rotate();
|
rotate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Actualiza las variables internas del objeto (time-based)
|
||||||
|
void MovingSprite::update(float deltaTime) {
|
||||||
|
move(deltaTime);
|
||||||
|
rotate(deltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
// Muestra el sprite por pantalla
|
// Muestra el sprite por pantalla
|
||||||
void MovingSprite::render() { getTexture()->render(pos_.x, pos_.y, &sprite_clip_, horizontal_zoom_, vertical_zoom_, rotate_.angle, &rotate_.center, flip_); }
|
void MovingSprite::render() { getTexture()->render(pos_.x, pos_.y, &sprite_clip_, horizontal_zoom_, vertical_zoom_, rotate_.angle, &rotate_.center, flip_); }
|
||||||
|
|
||||||
// Establece la rotacion
|
// Establece la rotacion (frame-based)
|
||||||
void MovingSprite::rotate() {
|
void MovingSprite::rotate() {
|
||||||
if (rotate_.enabled) {
|
if (rotate_.enabled) {
|
||||||
++rotate_.counter;
|
++rotate_.counter;
|
||||||
@@ -85,6 +103,15 @@ void MovingSprite::rotate() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Establece la rotacion (time-based)
|
||||||
|
void MovingSprite::rotate(float deltaTime) {
|
||||||
|
if (rotate_.enabled) {
|
||||||
|
// Convertir speed (frames) a tiempo: speed frames = speed/60 segundos a 60fps
|
||||||
|
float rotationSpeed = static_cast<float>(rotate_.speed) / 60.0f;
|
||||||
|
rotate_.angle += rotate_.amount * (deltaTime / rotationSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Activa o desactiva el efecto de rotación
|
// Activa o desactiva el efecto de rotación
|
||||||
void MovingSprite::setRotate(bool enable) {
|
void MovingSprite::setRotate(bool enable) {
|
||||||
rotate_.enabled = enable;
|
rotate_.enabled = enable;
|
||||||
|
|||||||
@@ -29,10 +29,11 @@ class MovingSprite : public Sprite {
|
|||||||
~MovingSprite() override = default;
|
~MovingSprite() override = default;
|
||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
virtual void update(); // Actualiza las variables internas del objeto
|
virtual void update(); // Actualiza las variables internas del objeto (frame-based)
|
||||||
void clear() override; // Reinicia todas las variables a cero
|
virtual void update(float deltaTime); // Actualiza las variables internas del objeto (time-based)
|
||||||
void stop(); // Elimina el movimiento del sprite
|
void clear() override; // Reinicia todas las variables a cero
|
||||||
void render() override; // Muestra el sprite por pantalla
|
void stop(); // Elimina el movimiento del sprite
|
||||||
|
void render() override; // Muestra el sprite por pantalla
|
||||||
|
|
||||||
// --- Configuración ---
|
// --- Configuración ---
|
||||||
void setPos(SDL_FRect rect); // Establece la posición y el tamaño del objeto
|
void setPos(SDL_FRect rect); // Establece la posición y el tamaño del objeto
|
||||||
@@ -79,6 +80,8 @@ class MovingSprite : public Sprite {
|
|||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
void updateAngle() { rotate_.angle += rotate_.amount; } // Incrementa el valor del ángulo
|
void updateAngle() { rotate_.angle += rotate_.amount; } // Incrementa el valor del ángulo
|
||||||
void move(); // Mueve el sprite según velocidad y aceleración
|
void move(); // Mueve el sprite según velocidad y aceleración (frame-based)
|
||||||
void rotate(); // Rota el sprite según los parámetros de rotación
|
void move(float deltaTime); // Mueve el sprite según velocidad y aceleración (time-based)
|
||||||
|
void rotate(); // Rota el sprite según los parámetros de rotación (frame-based)
|
||||||
|
void rotate(float deltaTime); // Rota el sprite según los parámetros de rotación (time-based)
|
||||||
};
|
};
|
||||||
@@ -4,6 +4,13 @@
|
|||||||
#include <functional> // Para function
|
#include <functional> // Para function
|
||||||
#include <utility> // Para move
|
#include <utility> // Para move
|
||||||
|
|
||||||
|
// Constructor para paths por puntos (compatibilidad)
|
||||||
|
Path::Path(const std::vector<SDL_FPoint> &spots_init, int waiting_counter_init)
|
||||||
|
: spots(spots_init), is_point_path(true) {
|
||||||
|
constexpr float FRAME_TIME_MS = 1000.0f / 60.0f;
|
||||||
|
waiting_time_ms = static_cast<float>(waiting_counter_init) * FRAME_TIME_MS;
|
||||||
|
}
|
||||||
|
|
||||||
// Devuelve un vector con los puntos que conforman la ruta
|
// Devuelve un vector con los puntos que conforman la ruta
|
||||||
auto createPath(float start, float end, PathType type, float fixed_pos, int steps, const std::function<double(double)> &easing_function) -> std::vector<SDL_FPoint> {
|
auto createPath(float start, float end, PathType type, float fixed_pos, int steps, const std::function<double(double)> &easing_function) -> std::vector<SDL_FPoint> {
|
||||||
std::vector<SDL_FPoint> v;
|
std::vector<SDL_FPoint> v;
|
||||||
@@ -32,10 +39,16 @@ auto createPath(float start, float end, PathType type, float fixed_pos, int step
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza la posición y comprueba si ha llegado a su destino
|
// Actualiza la posición y comprueba si ha llegado a su destino (compatibilidad)
|
||||||
void PathSprite::update() {
|
void PathSprite::update() {
|
||||||
|
constexpr float FRAME_TIME_MS = 1000.0f / 60.0f; // 16.67ms por frame a 60 FPS
|
||||||
|
update(FRAME_TIME_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actualiza la posición y comprueba si ha llegado a su destino
|
||||||
|
void PathSprite::update(float delta_time) {
|
||||||
if (enabled_ && !has_finished_) {
|
if (enabled_ && !has_finished_) {
|
||||||
moveThroughCurrentPath();
|
moveThroughCurrentPath(delta_time);
|
||||||
goToNextPathOrDie();
|
goToNextPathOrDie();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,7 +92,13 @@ void PathSprite::addPath(Path path, bool centered) {
|
|||||||
|
|
||||||
// Añade un recorrido
|
// Añade un recorrido
|
||||||
void PathSprite::addPath(int start, int end, PathType type, int fixed_pos, int steps, const std::function<double(double)> &easing_function, int waiting_counter) {
|
void PathSprite::addPath(int start, int end, PathType type, int fixed_pos, int steps, const std::function<double(double)> &easing_function, int waiting_counter) {
|
||||||
paths_.emplace_back(createPath(start, end, type, fixed_pos, steps, easing_function), waiting_counter);
|
// Convertir frames a milisegundos
|
||||||
|
constexpr float FRAME_TIME_MS = 1000.0f / 60.0f;
|
||||||
|
float duration_ms = static_cast<float>(steps) * FRAME_TIME_MS;
|
||||||
|
float waiting_ms = static_cast<float>(waiting_counter) * FRAME_TIME_MS;
|
||||||
|
|
||||||
|
paths_.emplace_back(static_cast<float>(start), static_cast<float>(end), type, static_cast<float>(fixed_pos),
|
||||||
|
duration_ms, waiting_ms, easing_function);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Añade un recorrido
|
// Añade un recorrido
|
||||||
@@ -95,35 +114,78 @@ void PathSprite::enable() {
|
|||||||
|
|
||||||
enabled_ = true;
|
enabled_ = true;
|
||||||
|
|
||||||
// Establece la posición
|
// Establece la posición inicial
|
||||||
auto &path = paths_.at(current_path_);
|
auto &path = paths_.at(current_path_);
|
||||||
const auto &p = path.spots.at(path.counter);
|
if (path.is_point_path) {
|
||||||
setPosition(p);
|
const auto &p = path.spots.at(path.counter);
|
||||||
|
setPosition(p);
|
||||||
|
} else {
|
||||||
|
// Para paths generados, establecer posición inicial
|
||||||
|
SDL_FPoint initial_pos;
|
||||||
|
if (path.type == PathType::HORIZONTAL) {
|
||||||
|
initial_pos = {path.start_pos, path.fixed_pos};
|
||||||
|
} else {
|
||||||
|
initial_pos = {path.fixed_pos, path.start_pos};
|
||||||
|
}
|
||||||
|
setPosition(initial_pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Coloca el sprite en los diferentes puntos del recorrido
|
// Coloca el sprite en los diferentes puntos del recorrido
|
||||||
void PathSprite::moveThroughCurrentPath() {
|
void PathSprite::moveThroughCurrentPath(float delta_time) {
|
||||||
auto &path = paths_.at(current_path_);
|
auto &path = paths_.at(current_path_);
|
||||||
|
|
||||||
// Establece la posición
|
if (path.is_point_path) {
|
||||||
const auto &p = path.spots.at(path.counter);
|
// Lógica para paths por puntos (compatibilidad)
|
||||||
setPosition(p);
|
const auto &p = path.spots.at(path.counter);
|
||||||
|
setPosition(p);
|
||||||
|
|
||||||
// Comprobar si ha terminado el recorrido
|
if (!path.on_destination) {
|
||||||
if (!path.on_destination) {
|
++path.counter;
|
||||||
++path.counter;
|
if (path.counter >= static_cast<int>(path.spots.size())) {
|
||||||
if (path.counter >= static_cast<int>(path.spots.size())) {
|
path.on_destination = true;
|
||||||
path.on_destination = true;
|
path.counter = static_cast<int>(path.spots.size()) - 1;
|
||||||
path.counter = static_cast<int>(path.spots.size()) - 1;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Comprobar si ha terminado la espera
|
if (path.on_destination) {
|
||||||
if (path.on_destination) {
|
path.waiting_elapsed += delta_time;
|
||||||
if (path.waiting_counter == 0) {
|
if (path.waiting_elapsed >= path.waiting_time_ms) {
|
||||||
path.finished = true;
|
path.finished = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Lógica para paths generados en tiempo real
|
||||||
|
if (!path.on_destination) {
|
||||||
|
path.elapsed_time += delta_time;
|
||||||
|
|
||||||
|
// Calcular progreso (0.0 a 1.0)
|
||||||
|
float progress = path.elapsed_time / path.duration_ms;
|
||||||
|
if (progress >= 1.0f) {
|
||||||
|
progress = 1.0f;
|
||||||
|
path.on_destination = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aplicar función de easing
|
||||||
|
double eased_progress = path.easing_function(progress);
|
||||||
|
|
||||||
|
// Calcular posición actual
|
||||||
|
float current_pos = path.start_pos + (path.end_pos - path.start_pos) * static_cast<float>(eased_progress);
|
||||||
|
|
||||||
|
// Establecer posición según el tipo
|
||||||
|
SDL_FPoint position;
|
||||||
|
if (path.type == PathType::HORIZONTAL) {
|
||||||
|
position = {current_pos, path.fixed_pos};
|
||||||
|
} else {
|
||||||
|
position = {path.fixed_pos, current_pos};
|
||||||
|
}
|
||||||
|
setPosition(position);
|
||||||
} else {
|
} else {
|
||||||
--path.waiting_counter;
|
// Esperar en destino
|
||||||
|
path.waiting_elapsed += delta_time;
|
||||||
|
if (path.waiting_elapsed >= path.waiting_time_ms) {
|
||||||
|
path.finished = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,17 +24,31 @@ enum class PathCentered { // Centrado del recorrido
|
|||||||
};
|
};
|
||||||
|
|
||||||
// --- Estructuras ---
|
// --- Estructuras ---
|
||||||
struct Path { // Define un recorrido para el sprite
|
struct Path { // Define un recorrido para el sprite
|
||||||
std::vector<SDL_FPoint> spots; // Puntos por los que se desplazará el sprite
|
float start_pos; // Posición inicial
|
||||||
int waiting_counter; // Tiempo de espera una vez en el destino
|
float end_pos; // Posición final
|
||||||
bool on_destination = false; // Indica si ha llegado al destino
|
PathType type; // Tipo de movimiento (horizontal/vertical)
|
||||||
bool finished = false; // Indica si ha terminado de esperarse
|
float fixed_pos; // Posición fija en el eje contrario
|
||||||
int counter = 0; // Contador interno
|
float duration_ms; // Duración de la animación en milisegundos
|
||||||
|
float waiting_time_ms; // Tiempo de espera una vez en el destino
|
||||||
|
std::function<double(double)> easing_function; // Función de easing
|
||||||
|
float elapsed_time = 0.0f; // Tiempo transcurrido
|
||||||
|
float waiting_elapsed = 0.0f; // Tiempo de espera transcurrido
|
||||||
|
bool on_destination = false; // Indica si ha llegado al destino
|
||||||
|
bool finished = false; // Indica si ha terminado de esperarse
|
||||||
|
|
||||||
// Constructor
|
// Constructor para paths generados
|
||||||
Path(const std::vector<SDL_FPoint> &spots_init, int waiting_counter_init)
|
Path(float start, float end, PathType path_type, float fixed, float duration, float waiting, std::function<double(double)> easing)
|
||||||
: spots(spots_init),
|
: start_pos(start), end_pos(end), type(path_type), fixed_pos(fixed),
|
||||||
waiting_counter(waiting_counter_init) {}
|
duration_ms(duration), waiting_time_ms(waiting), easing_function(std::move(easing)) {}
|
||||||
|
|
||||||
|
// Constructor para paths por puntos (mantenemos compatibilidad)
|
||||||
|
Path(const std::vector<SDL_FPoint> &spots_init, int waiting_counter_init);
|
||||||
|
|
||||||
|
// Variables para paths por puntos
|
||||||
|
std::vector<SDL_FPoint> spots; // Solo para paths por puntos
|
||||||
|
int counter = 0; // Solo para paths por puntos
|
||||||
|
bool is_point_path = false; // Indica si es un path por puntos
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Funciones ---
|
// --- Funciones ---
|
||||||
@@ -49,7 +63,8 @@ class PathSprite : public Sprite {
|
|||||||
~PathSprite() override = default;
|
~PathSprite() override = default;
|
||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
void update(); // Actualiza la posición del sprite según el recorrido
|
void update(); // Actualiza la posición del sprite según el recorrido (compatibilidad)
|
||||||
|
void update(float delta_time); // Actualiza la posición del sprite según el recorrido
|
||||||
void render() override; // Muestra el sprite por pantalla
|
void render() override; // Muestra el sprite por pantalla
|
||||||
|
|
||||||
// --- Gestión de recorridos ---
|
// --- Gestión de recorridos ---
|
||||||
@@ -72,6 +87,6 @@ class PathSprite : public Sprite {
|
|||||||
std::vector<Path> paths_; // Caminos a recorrer por el sprite
|
std::vector<Path> paths_; // Caminos a recorrer por el sprite
|
||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
void moveThroughCurrentPath(); // Coloca el sprite en los diferentes puntos del recorrido
|
void moveThroughCurrentPath(float delta_time); // Coloca el sprite en los diferentes puntos del recorrido
|
||||||
void goToNextPathOrDie(); // Cambia de recorrido o finaliza
|
void goToNextPathOrDie(); // Cambia de recorrido o finaliza
|
||||||
};
|
};
|
||||||
@@ -33,7 +33,7 @@ HiScoreTable::HiScoreTable()
|
|||||||
backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
|
backbuffer_(SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height)),
|
||||||
fade_(std::make_unique<Fade>()),
|
fade_(std::make_unique<Fade>()),
|
||||||
background_(std::make_unique<Background>()),
|
background_(std::make_unique<Background>()),
|
||||||
ticks_(0),
|
last_time_(0),
|
||||||
view_area_(SDL_FRect{0, 0, param.game.width, param.game.height}),
|
view_area_(SDL_FRect{0, 0, param.game.width, param.game.height}),
|
||||||
fade_mode_(Fade::Mode::IN),
|
fade_mode_(Fade::Mode::IN),
|
||||||
background_fade_color_(Color(0, 0, 0)) {
|
background_fade_color_(Color(0, 0, 0)) {
|
||||||
@@ -53,17 +53,14 @@ HiScoreTable::~HiScoreTable() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza las variables
|
// Actualiza las variables
|
||||||
void HiScoreTable::update() {
|
void HiScoreTable::update(float delta_time) {
|
||||||
if (SDL_GetTicks() - ticks_ > param.game.speed) {
|
Screen::get()->update(); // Actualiza el objeto screen
|
||||||
ticks_ = SDL_GetTicks(); // Actualiza el contador de ticks
|
|
||||||
Screen::get()->update(); // Actualiza el objeto screen
|
|
||||||
|
|
||||||
updateSprites(); // Actualiza las posiciones de los sprites de texto
|
updateSprites(delta_time); // Actualiza las posiciones de los sprites de texto
|
||||||
background_->update(); // Actualiza el fondo
|
background_->update(delta_time); // Actualiza el fondo
|
||||||
updateFade(); // Gestiona el fade
|
updateFade(delta_time); // Gestiona el fade
|
||||||
updateCounter(); // Gestiona el contador y sus eventos
|
updateCounter(); // Gestiona el contador y sus eventos
|
||||||
fillTexture(); // Dibuja los sprites en la textura
|
fillTexture(); // Dibuja los sprites en la textura
|
||||||
}
|
|
||||||
|
|
||||||
Audio::update();
|
Audio::update();
|
||||||
}
|
}
|
||||||
@@ -117,20 +114,32 @@ void HiScoreTable::checkInput() {
|
|||||||
GlobalInputs::check();
|
GlobalInputs::check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calcula el tiempo transcurrido desde el último frame
|
||||||
|
float HiScoreTable::calculateDeltaTime() {
|
||||||
|
const Uint64 current_time = SDL_GetTicks();
|
||||||
|
const float delta_time = static_cast<float>(current_time - last_time_);
|
||||||
|
last_time_ = current_time;
|
||||||
|
return delta_time;
|
||||||
|
}
|
||||||
|
|
||||||
// Bucle para la pantalla de instrucciones
|
// Bucle para la pantalla de instrucciones
|
||||||
void HiScoreTable::run() {
|
void HiScoreTable::run() {
|
||||||
|
last_time_ = SDL_GetTicks();
|
||||||
Audio::get()->playMusic("title.ogg");
|
Audio::get()->playMusic("title.ogg");
|
||||||
|
|
||||||
while (Section::name == Section::Name::HI_SCORE_TABLE) {
|
while (Section::name == Section::Name::HI_SCORE_TABLE) {
|
||||||
|
const float delta_time = calculateDeltaTime();
|
||||||
|
|
||||||
checkInput();
|
checkInput();
|
||||||
update();
|
update(delta_time);
|
||||||
checkEvents(); // Tiene que ir antes del render
|
checkEvents(); // Tiene que ir antes del render
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gestiona el fade
|
// Gestiona el fade
|
||||||
void HiScoreTable::updateFade() {
|
void HiScoreTable::updateFade(float delta_time) {
|
||||||
fade_->update();
|
fade_->update(delta_time);
|
||||||
|
|
||||||
if (fade_->hasEnded() && fade_mode_ == Fade::Mode::IN) {
|
if (fade_->hasEnded() && fade_mode_ == Fade::Mode::IN) {
|
||||||
fade_->reset();
|
fade_->reset();
|
||||||
@@ -249,7 +258,7 @@ void HiScoreTable::createSprites() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza las posiciones de los sprites de texto
|
// Actualiza las posiciones de los sprites de texto
|
||||||
void HiScoreTable::updateSprites() {
|
void HiScoreTable::updateSprites(float delta_time) {
|
||||||
constexpr int INIT_COUNTER = 190;
|
constexpr int INIT_COUNTER = 190;
|
||||||
const int COUNTER_BETWEEN_ENTRIES = 16;
|
const int COUNTER_BETWEEN_ENTRIES = 16;
|
||||||
if (counter_ >= INIT_COUNTER) {
|
if (counter_ >= INIT_COUNTER) {
|
||||||
@@ -262,7 +271,7 @@ void HiScoreTable::updateSprites() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto const &entry : entry_names_) {
|
for (auto const &entry : entry_names_) {
|
||||||
entry->update();
|
entry->update(delta_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
glowEntryNames();
|
glowEntryNames();
|
||||||
|
|||||||
@@ -45,26 +45,27 @@ class HiScoreTable {
|
|||||||
|
|
||||||
// --- Variables ---
|
// --- Variables ---
|
||||||
Uint16 counter_ = 0; // Contador
|
Uint16 counter_ = 0; // Contador
|
||||||
Uint64 ticks_; // Contador de ticks para ajustar la velocidad del programa
|
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
|
||||||
SDL_FRect view_area_; // Parte de la textura que se muestra en pantalla
|
SDL_FRect view_area_; // Parte de la textura que se muestra en pantalla
|
||||||
Fade::Mode fade_mode_; // Modo de fade a utilizar
|
Fade::Mode fade_mode_; // Modo de fade a utilizar
|
||||||
Color background_fade_color_; // Color de atenuación del fondo
|
Color background_fade_color_; // Color de atenuación del fondo
|
||||||
std::vector<Color> entry_colors_; // Colores para destacar las entradas en la tabla
|
std::vector<Color> entry_colors_; // Colores para destacar las entradas en la tabla
|
||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
void update(); // Actualiza las variables
|
void update(float delta_time); // Actualiza las variables
|
||||||
void render(); // Pinta en pantalla
|
void render(); // Pinta en pantalla
|
||||||
static void checkEvents(); // Comprueba los eventos
|
static void checkEvents(); // Comprueba los eventos
|
||||||
static void checkInput(); // Comprueba las entradas
|
static void checkInput(); // Comprueba las entradas
|
||||||
static auto format(int number) -> std::string; // Convierte un entero a un string con separadores de miles
|
static auto format(int number) -> std::string; // Convierte un entero a un string con separadores de miles
|
||||||
void fillTexture(); // Dibuja los sprites en la textura
|
void fillTexture(); // Dibuja los sprites en la textura
|
||||||
void updateFade(); // Gestiona el fade
|
void updateFade(float delta_time); // Gestiona el fade
|
||||||
void createSprites(); // Crea los sprites con los textos
|
void createSprites(); // Crea los sprites con los textos
|
||||||
void updateSprites(); // Actualiza las posiciones de los sprites de texto
|
void updateSprites(float delta_time); // Actualiza las posiciones de los sprites de texto
|
||||||
void initFade(); // Inicializa el fade
|
void initFade(); // Inicializa el fade
|
||||||
void initBackground(); // Inicializa el fondo
|
void initBackground(); // Inicializa el fondo
|
||||||
auto getEntryColor(int counter) -> Color; // Obtiene un color del vector de colores de entradas
|
auto getEntryColor(int counter) -> Color; // Obtiene un color del vector de colores de entradas
|
||||||
void iniEntryColors(); // Inicializa los colores de las entradas
|
void iniEntryColors(); // Inicializa los colores de las entradas
|
||||||
void glowEntryNames(); // Hace brillar los nombres de la tabla de records
|
void glowEntryNames(); // Hace brillar los nombres de la tabla de records
|
||||||
void updateCounter(); // Gestiona el contador
|
void updateCounter(); // Gestiona el contador
|
||||||
|
float calculateDeltaTime(); // Calcula el tiempo transcurrido desde el último frame
|
||||||
};
|
};
|
||||||
@@ -204,18 +204,15 @@ void Instructions::fillBackbuffer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza las variables
|
// Actualiza las variables
|
||||||
void Instructions::update() {
|
void Instructions::update(float delta_time) {
|
||||||
if (SDL_GetTicks() - ticks_ > param.game.speed) {
|
Screen::get()->update(); // Actualiza el objeto screen
|
||||||
ticks_ = SDL_GetTicks(); // Actualiza el contador de ticks
|
|
||||||
Screen::get()->update(); // Actualiza el objeto screen
|
|
||||||
|
|
||||||
counter_++; // Incrementa el contador
|
counter_++; // Incrementa el contador
|
||||||
updateSprites(); // Actualiza los sprites
|
updateSprites(); // Actualiza los sprites
|
||||||
updateBackbuffer(); // Gestiona la textura con los graficos
|
updateBackbuffer(); // Gestiona la textura con los graficos
|
||||||
tiled_bg_->update(); // Actualiza el mosaico de fondo
|
tiled_bg_->update(delta_time); // Actualiza el mosaico de fondo
|
||||||
fade_->update(); // Actualiza el objeto "fade"
|
fade_->update(delta_time); // Actualiza el objeto "fade"
|
||||||
fillBackbuffer(); // Rellena el backbuffer
|
fillBackbuffer(); // Rellena el backbuffer
|
||||||
}
|
|
||||||
|
|
||||||
Audio::update();
|
Audio::update();
|
||||||
}
|
}
|
||||||
@@ -255,12 +252,24 @@ void Instructions::checkInput() {
|
|||||||
GlobalInputs::check();
|
GlobalInputs::check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calcula el tiempo transcurrido desde el último frame
|
||||||
|
float Instructions::calculateDeltaTime() {
|
||||||
|
const Uint64 current_time = SDL_GetTicks();
|
||||||
|
const float delta_time = static_cast<float>(current_time - last_time_);
|
||||||
|
last_time_ = current_time;
|
||||||
|
return delta_time;
|
||||||
|
}
|
||||||
|
|
||||||
// Bucle para la pantalla de instrucciones
|
// Bucle para la pantalla de instrucciones
|
||||||
void Instructions::run() {
|
void Instructions::run() {
|
||||||
|
last_time_ = SDL_GetTicks();
|
||||||
Audio::get()->playMusic("title.ogg");
|
Audio::get()->playMusic("title.ogg");
|
||||||
|
|
||||||
while (Section::name == Section::Name::INSTRUCTIONS) {
|
while (Section::name == Section::Name::INSTRUCTIONS) {
|
||||||
|
const float delta_time = calculateDeltaTime();
|
||||||
|
|
||||||
checkInput();
|
checkInput();
|
||||||
update();
|
update(delta_time);
|
||||||
checkEvents(); // Tiene que ir antes del render
|
checkEvents(); // Tiene que ir antes del render
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class Instructions {
|
|||||||
|
|
||||||
// --- Variables ---
|
// --- Variables ---
|
||||||
int counter_ = 0; // Contador para manejar el progreso en la pantalla de instrucciones
|
int counter_ = 0; // Contador para manejar el progreso en la pantalla de instrucciones
|
||||||
Uint64 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
|
||||||
SDL_FRect view_; // Vista del backbuffer que se va a mostrar por pantalla
|
SDL_FRect view_; // Vista del backbuffer que se va a mostrar por pantalla
|
||||||
SDL_FPoint sprite_pos_ = {0, 0}; // Posición del primer sprite en la lista
|
SDL_FPoint sprite_pos_ = {0, 0}; // Posición del primer sprite en la lista
|
||||||
float item_space_ = 2.0; // Espacio entre los items en pantalla
|
float item_space_ = 2.0; // Espacio entre los items en pantalla
|
||||||
@@ -73,7 +73,7 @@ class Instructions {
|
|||||||
bool start_delay_triggered_ = false; // Bandera para determinar si el retraso ha comenzado
|
bool start_delay_triggered_ = false; // Bandera para determinar si el retraso ha comenzado
|
||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
void update(); // Actualiza las variables
|
void update(float delta_time); // Actualiza las variables
|
||||||
void render(); // Pinta en pantalla
|
void render(); // Pinta en pantalla
|
||||||
static void checkEvents(); // Comprueba los eventos
|
static void checkEvents(); // Comprueba los eventos
|
||||||
static void checkInput(); // Comprueba las entradas
|
static void checkInput(); // Comprueba las entradas
|
||||||
@@ -82,7 +82,8 @@ class Instructions {
|
|||||||
void iniSprites(); // Inicializa los sprites de los items
|
void iniSprites(); // Inicializa los sprites de los items
|
||||||
void updateSprites(); // Actualiza los sprites
|
void updateSprites(); // Actualiza los sprites
|
||||||
static auto initializeLines(int height) -> std::vector<Line>; // Inicializa las líneas animadas
|
static auto initializeLines(int height) -> std::vector<Line>; // Inicializa las líneas animadas
|
||||||
static auto moveLines(std::vector<Line> &lines, int width, float duration, Uint32 start_delay) -> bool; // Mueve las líneas
|
static auto moveLines(std::vector<Line> &lines, int width, float duration, Uint32 start_delay) -> bool; // Mueve las líneas (ya usa tiempo real)
|
||||||
static void renderLines(SDL_Renderer *renderer, SDL_Texture *texture, const std::vector<Line> &lines); // Renderiza las líneas
|
static void renderLines(SDL_Renderer *renderer, SDL_Texture *texture, const std::vector<Line> &lines); // Renderiza las líneas
|
||||||
void updateBackbuffer(); // Gestiona la textura con los gráficos
|
void updateBackbuffer(); // Gestiona la textura con los gráficos
|
||||||
|
float calculateDeltaTime(); // Calcula el tiempo transcurrido desde el último frame
|
||||||
};
|
};
|
||||||
@@ -207,24 +207,21 @@ void Intro::switchText(int from_index, int to_index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza las variables del objeto
|
// Actualiza las variables del objeto
|
||||||
void Intro::update() {
|
void Intro::update(float delta_time) {
|
||||||
if (SDL_GetTicks() - ticks_ > param.game.speed) {
|
Screen::get()->update(); // Actualiza el objeto screen
|
||||||
ticks_ = SDL_GetTicks(); // Actualiza el contador de ticks
|
|
||||||
Screen::get()->update(); // Actualiza el objeto screen
|
|
||||||
|
|
||||||
tiled_bg_->update(); // Actualiza el fondo
|
tiled_bg_->update(delta_time); // Actualiza el fondo
|
||||||
|
|
||||||
switch (state_) {
|
switch (state_) {
|
||||||
case State::SCENES:
|
case State::SCENES:
|
||||||
updateSprites();
|
updateSprites(delta_time);
|
||||||
updateTexts();
|
updateTexts(delta_time);
|
||||||
updateScenes();
|
updateScenes();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case State::POST:
|
case State::POST:
|
||||||
updatePostState();
|
updatePostState();
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Audio::update();
|
Audio::update();
|
||||||
@@ -253,12 +250,24 @@ void Intro::render() {
|
|||||||
SCREEN->render(); // Vuelca el contenido del renderizador en pantalla
|
SCREEN->render(); // Vuelca el contenido del renderizador en pantalla
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calcula el tiempo transcurrido desde el último frame
|
||||||
|
float Intro::calculateDeltaTime() {
|
||||||
|
const Uint64 current_time = SDL_GetTicks();
|
||||||
|
const float delta_time = static_cast<float>(current_time - last_time_);
|
||||||
|
last_time_ = current_time;
|
||||||
|
return delta_time;
|
||||||
|
}
|
||||||
|
|
||||||
// Bucle principal
|
// Bucle principal
|
||||||
void Intro::run() {
|
void Intro::run() {
|
||||||
|
last_time_ = SDL_GetTicks();
|
||||||
Audio::get()->playMusic("intro.ogg", 0);
|
Audio::get()->playMusic("intro.ogg", 0);
|
||||||
|
|
||||||
while (Section::name == Section::Name::INTRO) {
|
while (Section::name == Section::Name::INTRO) {
|
||||||
|
const float delta_time = calculateDeltaTime();
|
||||||
|
|
||||||
checkInput();
|
checkInput();
|
||||||
update();
|
update(delta_time);
|
||||||
checkEvents(); // Tiene que ir antes del render
|
checkEvents(); // Tiene que ir antes del render
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
@@ -444,20 +453,20 @@ void Intro::initTexts() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza los sprites
|
// Actualiza los sprites
|
||||||
void Intro::updateSprites() {
|
void Intro::updateSprites(float delta_time) {
|
||||||
for (auto &sprite : card_sprites_) {
|
for (auto &sprite : card_sprites_) {
|
||||||
sprite->update();
|
sprite->update(delta_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &sprite : shadow_sprites_) {
|
for (auto &sprite : shadow_sprites_) {
|
||||||
sprite->update();
|
sprite->update(delta_time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza los textos
|
// Actualiza los textos
|
||||||
void Intro::updateTexts() {
|
void Intro::updateTexts(float delta_time) {
|
||||||
for (auto &text : texts_) {
|
for (auto &text : texts_) {
|
||||||
text->update();
|
text->update(delta_time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class Intro {
|
|||||||
std::unique_ptr<TiledBG> tiled_bg_; // Fondo en mosaico
|
std::unique_ptr<TiledBG> tiled_bg_; // Fondo en mosaico
|
||||||
|
|
||||||
// --- Variables ---
|
// --- Variables ---
|
||||||
Uint64 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
|
||||||
int scene_ = 0; // Indica qué escena está activa
|
int scene_ = 0; // Indica qué escena está activa
|
||||||
State state_ = State::SCENES; // Estado principal de la intro
|
State state_ = State::SCENES; // Estado principal de la intro
|
||||||
PostState post_state_ = PostState::STOP_BG; // Estado POST
|
PostState post_state_ = PostState::STOP_BG; // Estado POST
|
||||||
@@ -50,19 +50,20 @@ class Intro {
|
|||||||
Color bg_color_ = param.intro.bg_color; // Color de fondo
|
Color bg_color_ = param.intro.bg_color; // Color de fondo
|
||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
void update(); // Actualiza las variables del objeto
|
void update(float delta_time); // Actualiza las variables del objeto
|
||||||
void render(); // Dibuja el objeto en pantalla
|
void render(); // Dibuja el objeto en pantalla
|
||||||
static void checkInput(); // Comprueba las entradas
|
static void checkInput(); // Comprueba las entradas
|
||||||
static void checkEvents(); // Comprueba los eventos
|
static void checkEvents(); // Comprueba los eventos
|
||||||
void updateScenes(); // Actualiza las escenas de la intro
|
void updateScenes(); // Actualiza las escenas de la intro
|
||||||
void initSprites(); // Inicializa las imágenes
|
void initSprites(); // Inicializa las imágenes
|
||||||
void initTexts(); // Inicializa los textos
|
void initTexts(); // Inicializa los textos
|
||||||
void updateSprites(); // Actualiza los sprites
|
void updateSprites(float delta_time); // Actualiza los sprites
|
||||||
void updateTexts(); // Actualiza los textos
|
void updateTexts(float delta_time); // Actualiza los textos
|
||||||
void renderSprites(); // Dibuja los sprites
|
void renderSprites(); // Dibuja los sprites
|
||||||
void renderTexts(); // Dibuja los textos
|
void renderTexts(); // Dibuja los textos
|
||||||
static void renderTextRect(); // Dibuja el rectangulo de fondo del texto;
|
static void renderTextRect(); // Dibuja el rectangulo de fondo del texto;
|
||||||
void updatePostState(); // Actualiza el estado POST
|
void updatePostState(); // Actualiza el estado POST
|
||||||
|
float calculateDeltaTime(); // Calcula el tiempo transcurrido desde el último frame
|
||||||
|
|
||||||
// --- Métodos para manejar cada escena individualmente ---
|
// --- Métodos para manejar cada escena individualmente ---
|
||||||
void updateScene0();
|
void updateScene0();
|
||||||
|
|||||||
@@ -79,21 +79,23 @@ void Logo::checkInput() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Gestiona el logo de JAILGAMES
|
// Gestiona el logo de JAILGAMES
|
||||||
void Logo::updateJAILGAMES() {
|
void Logo::updateJAILGAMES(float delta_time) {
|
||||||
if (counter_ == 30) {
|
if (counter_ == 30) {
|
||||||
Audio::get()->playSound("logo.wav");
|
Audio::get()->playSound("logo.wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (counter_ > 30) {
|
if (counter_ > 30) {
|
||||||
|
const float pixels_to_move = SPEED * delta_time;
|
||||||
|
|
||||||
for (int i = 0; i < (int)jail_sprite_.size(); ++i) {
|
for (int i = 0; i < (int)jail_sprite_.size(); ++i) {
|
||||||
if (jail_sprite_[i]->getX() != dest_.x) {
|
if (jail_sprite_[i]->getX() != dest_.x) {
|
||||||
if (i % 2 == 0) {
|
if (i % 2 == 0) {
|
||||||
jail_sprite_[i]->incX(-SPEED);
|
jail_sprite_[i]->incX(-pixels_to_move);
|
||||||
if (jail_sprite_[i]->getX() < dest_.x) {
|
if (jail_sprite_[i]->getX() < dest_.x) {
|
||||||
jail_sprite_[i]->setX(dest_.x);
|
jail_sprite_[i]->setX(dest_.x);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
jail_sprite_[i]->incX(SPEED);
|
jail_sprite_[i]->incX(pixels_to_move);
|
||||||
if (jail_sprite_[i]->getX() > dest_.x) {
|
if (jail_sprite_[i]->getX() > dest_.x) {
|
||||||
jail_sprite_[i]->setX(dest_.x);
|
jail_sprite_[i]->setX(dest_.x);
|
||||||
}
|
}
|
||||||
@@ -129,16 +131,21 @@ void Logo::updateTextureColors() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza las variables
|
// Actualiza las variables
|
||||||
void Logo::update() {
|
void Logo::update(float delta_time) {
|
||||||
if (SDL_GetTicks() - ticks_ > param.game.speed) {
|
static float logic_accumulator = 0.0f;
|
||||||
ticks_ = SDL_GetTicks(); // Actualiza el contador de ticks
|
logic_accumulator += delta_time;
|
||||||
Screen::get()->update(); // Actualiza el objeto screen
|
|
||||||
|
|
||||||
updateJAILGAMES(); // Actualiza el logo de JAILGAMES
|
// Ejecutar lógica a 60 FPS (cada 16.67ms) para mantener consistencia en counter_ y colores
|
||||||
|
constexpr float LOGIC_FRAME_TIME = 1000.0f / 60.0f;
|
||||||
|
|
||||||
|
if (logic_accumulator >= LOGIC_FRAME_TIME) {
|
||||||
|
Screen::get()->update(); // Actualiza el objeto screen
|
||||||
updateTextureColors(); // Actualiza los colores de las texturas
|
updateTextureColors(); // Actualiza los colores de las texturas
|
||||||
++counter_; // Gestiona el contador
|
++counter_; // Gestiona el contador
|
||||||
|
logic_accumulator -= LOGIC_FRAME_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateJAILGAMES(delta_time); // Actualiza el logo de JAILGAMES con delta-time real
|
||||||
Audio::update();
|
Audio::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,11 +161,23 @@ void Logo::render() {
|
|||||||
SCREEN->render();
|
SCREEN->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calcula el tiempo transcurrido desde el último frame
|
||||||
|
float Logo::calculateDeltaTime() {
|
||||||
|
const Uint64 current_time = SDL_GetTicks();
|
||||||
|
const float delta_time = static_cast<float>(current_time - last_time_);
|
||||||
|
last_time_ = current_time;
|
||||||
|
return delta_time;
|
||||||
|
}
|
||||||
|
|
||||||
// Bucle para el logo del juego
|
// Bucle para el logo del juego
|
||||||
void Logo::run() {
|
void Logo::run() {
|
||||||
|
last_time_ = SDL_GetTicks();
|
||||||
|
|
||||||
while (Section::name == Section::Name::LOGO) {
|
while (Section::name == Section::Name::LOGO) {
|
||||||
|
const float delta_time = calculateDeltaTime();
|
||||||
|
|
||||||
checkInput();
|
checkInput();
|
||||||
update();
|
update(delta_time);
|
||||||
checkEvents(); // Tiene que ir antes del render
|
checkEvents(); // Tiene que ir antes del render
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class Logo {
|
|||||||
static constexpr int INIT_FADE_COUNTER_MARK = 300; // Tiempo del contador cuando inicia el fade a negro
|
static constexpr int INIT_FADE_COUNTER_MARK = 300; // Tiempo del contador cuando inicia el fade a negro
|
||||||
static constexpr int END_LOGO_COUNTER_MARK = 400; // Tiempo del contador para terminar el logo
|
static constexpr int END_LOGO_COUNTER_MARK = 400; // Tiempo del contador para terminar el logo
|
||||||
static constexpr int POST_LOGO_DURATION = 20; // Tiempo que dura el logo con el fade al máximo
|
static constexpr int POST_LOGO_DURATION = 20; // Tiempo que dura el logo con el fade al máximo
|
||||||
static constexpr int SPEED = 8; // Velocidad de desplazamiento de cada línea
|
static constexpr float SPEED = 8.0f / 15.0f; // Velocidad de desplazamiento de cada línea (píxeles por ms)
|
||||||
|
|
||||||
// --- Objetos y punteros ---
|
// --- Objetos y punteros ---
|
||||||
std::shared_ptr<Texture> since_texture_; // Textura con los gráficos "Since 1998"
|
std::shared_ptr<Texture> since_texture_; // Textura con los gráficos "Since 1998"
|
||||||
@@ -42,15 +42,16 @@ class Logo {
|
|||||||
// --- Variables ---
|
// --- Variables ---
|
||||||
std::vector<Color> color_; // Vector con los colores para el fade
|
std::vector<Color> color_; // Vector con los colores para el fade
|
||||||
int counter_ = 0; // Contador
|
int counter_ = 0; // Contador
|
||||||
Uint64 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
|
Uint64 last_time_ = 0; // Último timestamp para calcular delta-time
|
||||||
SDL_FPoint dest_; // Posición donde dibujar el logo
|
SDL_FPoint dest_; // Posición donde dibujar el logo
|
||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
void update(); // Actualiza las variables
|
void update(float delta_time); // Actualiza las variables
|
||||||
void render(); // Dibuja en pantalla
|
void render(); // Dibuja en pantalla
|
||||||
static void checkEvents(); // Comprueba el manejador de eventos
|
static void checkEvents(); // Comprueba el manejador de eventos
|
||||||
static void checkInput(); // Comprueba las entradas
|
static void checkInput(); // Comprueba las entradas
|
||||||
void updateJAILGAMES(); // Gestiona el logo de JAILGAMES
|
void updateJAILGAMES(float delta_time); // Gestiona el logo de JAILGAMES
|
||||||
void renderJAILGAMES(); // Renderiza el logo de JAILGAMES
|
void renderJAILGAMES(); // Renderiza el logo de JAILGAMES
|
||||||
void updateTextureColors(); // Gestiona el color de las texturas
|
void updateTextureColors(); // Gestiona el color de las texturas
|
||||||
|
float calculateDeltaTime(); // Calcula el tiempo transcurrido desde el último frame
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -81,9 +81,15 @@ void TiledBG::render() {
|
|||||||
SDL_RenderTexture(renderer_, canvas_, &window_, &pos_);
|
SDL_RenderTexture(renderer_, canvas_, &window_, &pos_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actualiza la lógica de la clase
|
// Actualiza la lógica de la clase (compatibilidad)
|
||||||
void TiledBG::update() {
|
void TiledBG::update() {
|
||||||
updateDesp();
|
constexpr float FRAME_TIME_MS = 1000.0f / 60.0f; // 16.67ms por frame a 60 FPS
|
||||||
|
update(FRAME_TIME_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actualiza la lógica de la clase
|
||||||
|
void TiledBG::update(float delta_time) {
|
||||||
|
updateDesp(delta_time);
|
||||||
updateStop();
|
updateStop();
|
||||||
|
|
||||||
switch (mode_) {
|
switch (mode_) {
|
||||||
|
|||||||
@@ -24,8 +24,9 @@ class TiledBG {
|
|||||||
~TiledBG();
|
~TiledBG();
|
||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
void render(); // Pinta la clase en pantalla
|
void render(); // Pinta la clase en pantalla
|
||||||
void update(); // Actualiza la lógica de la clase
|
void update(); // Actualiza la lógica de la clase (compatibilidad)
|
||||||
|
void update(float delta_time); // Actualiza la lógica de la clase
|
||||||
|
|
||||||
// --- Configuración ---
|
// --- Configuración ---
|
||||||
void setSpeed(float speed) { speed_ = speed; } // Establece la velocidad
|
void setSpeed(float speed) { speed_ = speed; } // Establece la velocidad
|
||||||
@@ -54,7 +55,8 @@ class TiledBG {
|
|||||||
bool stopping_ = false; // Indica si se está deteniendo
|
bool stopping_ = false; // Indica si se está deteniendo
|
||||||
|
|
||||||
// --- Métodos internos ---
|
// --- Métodos internos ---
|
||||||
void fillTexture(); // Rellena la textura con el contenido
|
void fillTexture(); // Rellena la textura con el contenido
|
||||||
void updateDesp() { desp_ += speed_; } // Actualiza el desplazamiento
|
void updateDesp() { desp_ += speed_; } // Actualiza el desplazamiento (compatibilidad)
|
||||||
void updateStop(); // Detiene el desplazamiento de forma ordenada
|
void updateDesp(float delta_time) { desp_ += speed_ * delta_time / (1000.0f / 60.0f); } // Actualiza el desplazamiento
|
||||||
|
void updateStop(); // Detiene el desplazamiento de forma ordenada
|
||||||
};
|
};
|
||||||
@@ -3,15 +3,14 @@
|
|||||||
#include "text.h" // Para Text
|
#include "text.h" // Para Text
|
||||||
|
|
||||||
// Actualiza el objeto
|
// Actualiza el objeto
|
||||||
void Writer::update() {
|
void Writer::update(float delta_time) {
|
||||||
if (enabled_) {
|
if (enabled_) {
|
||||||
if (!completed_) {
|
if (!completed_) {
|
||||||
// No completado
|
// No completado
|
||||||
if (writing_counter_ > 0) {
|
writing_timer_ += delta_time;
|
||||||
writing_counter_--;
|
if (writing_timer_ >= speed_ms_) {
|
||||||
} else {
|
|
||||||
index_++;
|
index_++;
|
||||||
writing_counter_ = speed_;
|
writing_timer_ = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index_ == length_) {
|
if (index_ == length_) {
|
||||||
@@ -19,10 +18,8 @@ void Writer::update() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Completado
|
// Completado
|
||||||
finished_ = enabled_counter_ <= 0;
|
enabled_timer_ += delta_time;
|
||||||
if (!finished_) {
|
finished_ = enabled_timer_ >= enabled_timer_target_;
|
||||||
enabled_counter_--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,8 +54,10 @@ void Writer::setCaption(const std::string &text) {
|
|||||||
|
|
||||||
// Establece el valor de la variable
|
// Establece el valor de la variable
|
||||||
void Writer::setSpeed(int value) {
|
void Writer::setSpeed(int value) {
|
||||||
speed_ = value;
|
// Convierte frames a milisegundos (frames * 16.67ms)
|
||||||
writing_counter_ = value;
|
constexpr float FRAME_TIME_MS = 1000.0f / 60.0f;
|
||||||
|
speed_ms_ = static_cast<float>(value) * FRAME_TIME_MS;
|
||||||
|
writing_timer_ = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Establece el valor de la variable
|
// Establece el valor de la variable
|
||||||
@@ -73,7 +72,10 @@ auto Writer::isEnabled() const -> bool {
|
|||||||
|
|
||||||
// Establece el valor de la variable
|
// Establece el valor de la variable
|
||||||
void Writer::setFinishedCounter(int time) {
|
void Writer::setFinishedCounter(int time) {
|
||||||
enabled_counter_ = time;
|
// Convierte frames a milisegundos (frames * 16.67ms)
|
||||||
|
constexpr float FRAME_TIME_MS = 1000.0f / 60.0f;
|
||||||
|
enabled_timer_target_ = static_cast<float>(time) * FRAME_TIME_MS;
|
||||||
|
enabled_timer_ = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Centra la cadena de texto a un punto X
|
// Centra la cadena de texto a un punto X
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class Writer {
|
|||||||
~Writer() = default;
|
~Writer() = default;
|
||||||
|
|
||||||
// --- Métodos principales ---
|
// --- Métodos principales ---
|
||||||
void update(); // Actualiza el objeto
|
void update(float delta_time); // Actualiza el objeto
|
||||||
void render() const; // Dibuja el objeto en pantalla
|
void render() const; // Dibuja el objeto en pantalla
|
||||||
|
|
||||||
// --- Setters ---
|
// --- Setters ---
|
||||||
@@ -38,16 +38,17 @@ class Writer {
|
|||||||
std::shared_ptr<Text> text_; // Objeto encargado de escribir el texto
|
std::shared_ptr<Text> text_; // Objeto encargado de escribir el texto
|
||||||
|
|
||||||
// --- Variables de estado ---
|
// --- Variables de estado ---
|
||||||
std::string caption_; // El texto para escribir
|
std::string caption_; // El texto para escribir
|
||||||
int pos_x_ = 0; // Posición en el eje X donde empezar a escribir el texto
|
int pos_x_ = 0; // Posición en el eje X donde empezar a escribir el texto
|
||||||
int pos_y_ = 0; // Posición en el eje Y donde empezar a escribir el texto
|
int pos_y_ = 0; // Posición en el eje Y donde empezar a escribir el texto
|
||||||
int kerning_ = 0; // Kerning del texto, es decir, espaciado entre caracteres
|
int kerning_ = 0; // Kerning del texto, es decir, espaciado entre caracteres
|
||||||
int speed_ = 0; // Velocidad de escritura
|
float speed_ms_ = 0.0f; // Velocidad de escritura en milisegundos
|
||||||
int writing_counter_ = 0; // Temporizador de escritura para cada caracter
|
float writing_timer_ = 0.0f; // Temporizador de escritura para cada caracter
|
||||||
int index_ = 0; // Posición del texto que se está escribiendo
|
int index_ = 0; // Posición del texto que se está escribiendo
|
||||||
int length_ = 0; // Longitud de la cadena a escribir
|
int length_ = 0; // Longitud de la cadena a escribir
|
||||||
int enabled_counter_ = 0; // Temporizador para deshabilitar el objeto
|
float enabled_timer_ = 0.0f; // Temporizador para deshabilitar el objeto
|
||||||
bool completed_ = false; // Indica si se ha escrito todo el texto
|
float enabled_timer_target_ = 0.0f; // Tiempo objetivo para deshabilitar el objeto
|
||||||
bool enabled_ = false; // Indica si el objeto está habilitado
|
bool completed_ = false; // Indica si se ha escrito todo el texto
|
||||||
bool finished_ = false; // Indica si ya ha terminado
|
bool enabled_ = false; // Indica si el objeto está habilitado
|
||||||
|
bool finished_ = false; // Indica si ya ha terminado
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user