From a96a17e11b59fbefa88eadd913b6b22768fe66f6 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 16 Sep 2025 20:29:35 +0200 Subject: [PATCH] delta-time: tabe.cpp --- source/tabe.cpp | 103 ++++++++++++++++++++++++++++++++++++++++++++++-- source/tabe.h | 15 ++++--- 2 files changed, 108 insertions(+), 10 deletions(-) diff --git a/source/tabe.cpp b/source/tabe.cpp index 5cee1a6..655334d 100644 --- a/source/tabe.cpp +++ b/source/tabe.cpp @@ -17,7 +17,7 @@ Tabe::Tabe() : sprite_(std::make_unique(Resource::get()->getTexture("tabe.png"), Resource::get()->getAnimation("tabe.ani"))), timer_(Timer(param.tabe.min_spawn_time, param.tabe.max_spawn_time)) {} -// Actualiza la lógica +// Actualiza la lógica (frame-based) void Tabe::update() { if (enabled_ && !timer_.is_paused) { sprite_->update(); @@ -31,6 +31,20 @@ void Tabe::update() { } } +// Actualiza la lógica (time-based) +void Tabe::update(float deltaTime) { + if (enabled_ && !timer_.is_paused) { + sprite_->update(deltaTime); + move(deltaTime); + updateState(deltaTime); + } + + timer_.update(); + if (timer_.shouldSpawn()) { + enable(); + } +} + // Dibuja el objeto void Tabe::render() { if (enabled_) { @@ -38,7 +52,7 @@ void Tabe::render() { } } -// Mueve el objeto +// Mueve el objeto (frame-based) void Tabe::move() { const int X = static_cast(x_); speed_ += accel_; @@ -103,6 +117,75 @@ void Tabe::move() { shiftSprite(); } +// Mueve el objeto (time-based) +void Tabe::move(float deltaTime) { + // Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps) + float frameFactor = deltaTime / (1000.0f / 60.0f); + + const int X = static_cast(x_); + speed_ += accel_ * frameFactor; + x_ += speed_ * frameFactor; + fly_distance_ -= std::abs(X - static_cast(x_)); + + // Comprueba si sale por los bordes + const float MIN_X = param.game.game_area.rect.x - WIDTH; + const float MAX_X = param.game.game_area.rect.x + param.game.game_area.rect.w; + switch (destiny_) { + case Direction::TO_THE_LEFT: { + if (x_ < MIN_X) { + disable(); + } + if (x_ > param.game.game_area.rect.x + param.game.game_area.rect.w - WIDTH && direction_ == Direction::TO_THE_RIGHT) { + setRandomFlyPath(Direction::TO_THE_LEFT, 80); + x_ = param.game.game_area.rect.x + param.game.game_area.rect.w - WIDTH; + } + break; + } + + case Direction::TO_THE_RIGHT: { + if (x_ > MAX_X) { + disable(); + } + if (x_ < param.game.game_area.rect.x && direction_ == Direction::TO_THE_LEFT) { + setRandomFlyPath(Direction::TO_THE_RIGHT, 80); + x_ = param.game.game_area.rect.x; + } + break; + } + default: + break; + } + + if (fly_distance_ <= 0) { + if (waiting_counter_ > 0) { + accel_ = speed_ = 0.0F; + waiting_counter_ -= frameFactor; + if (waiting_counter_ < 0) waiting_counter_ = 0; + } else { + constexpr int CHOICES = 4; + const std::array LEFT = { + Direction::TO_THE_LEFT, + Direction::TO_THE_LEFT, + Direction::TO_THE_LEFT, + Direction::TO_THE_RIGHT}; + + const std::array RIGHT = { + Direction::TO_THE_LEFT, + Direction::TO_THE_RIGHT, + Direction::TO_THE_RIGHT, + Direction::TO_THE_RIGHT}; + + const Direction DIRECTION = destiny_ == Direction::TO_THE_LEFT + ? LEFT[rand() % CHOICES] + : RIGHT[rand() % CHOICES]; + + setRandomFlyPath(DIRECTION, 20 + (rand() % 40)); + } + } + + shiftSprite(); +} + // Habilita el objeto void Tabe::enable() { if (!enabled_) { @@ -175,11 +258,23 @@ void Tabe::setState(State state) { } } -// Actualiza el estado +// Actualiza el estado (frame-based) void Tabe::updateState() { if (state_ == State::HIT) { --hit_counter_; - if (hit_counter_ == 0) { + if (hit_counter_ <= 0) { + setState(State::FLY); + } + } +} + +// Actualiza el estado (time-based) +void Tabe::updateState(float deltaTime) { + if (state_ == State::HIT) { + // Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps) + float frameFactor = deltaTime / (1000.0f / 60.0f); + hit_counter_ -= frameFactor; + if (hit_counter_ <= 0) { setState(State::FLY); } } diff --git a/source/tabe.h b/source/tabe.h index 7b392b2..2c5c21e 100644 --- a/source/tabe.h +++ b/source/tabe.h @@ -26,8 +26,9 @@ class Tabe { ~Tabe() = default; // --- Métodos principales --- - void update(); // Actualiza la lógica - void render(); // Dibuja el objeto + void update(); // Actualiza la lógica (frame-based) + void update(float deltaTime); // Actualiza la lógica (time-based) + void render(); // Dibuja el objeto void enable(); // Habilita el objeto void setState(State state); // Establece el estado auto tryToGetBonus() -> bool; // Intenta obtener el bonus @@ -130,21 +131,23 @@ class Tabe { float speed_ = 0.0F; // Velocidad de movimiento float accel_ = 0.0F; // Aceleración int fly_distance_ = 0; // Distancia de vuelo - int waiting_counter_ = 0; // Tiempo que pasa quieto + float waiting_counter_ = 0; // Tiempo que pasa quieto bool enabled_ = false; // Indica si el objeto está activo Direction direction_ = Direction::TO_THE_LEFT; // Dirección actual Direction destiny_ = Direction::TO_THE_LEFT; // Destino State state_ = State::FLY; // Estado actual - int hit_counter_ = 0; // Contador para el estado HIT + float hit_counter_ = 0; // Contador para el estado HIT int number_of_hits_ = 0; // Cantidad de disparos recibidos bool has_bonus_ = true; // Indica si aún tiene el bonus para soltar Timer timer_; // Temporizador para gestionar la aparición // --- Métodos internos --- - void move(); // Mueve el objeto + void move(); // Mueve el objeto (frame-based) + void move(float deltaTime); // Mueve el objeto (time-based) void shiftSprite() { sprite_->setPos(x_, y_); } // Actualiza la posición del sprite void setRandomFlyPath(Direction direction, int length); // Establece un vuelo aleatorio - void updateState(); // Actualiza el estado + void updateState(); // Actualiza el estado (frame-based) + void updateState(float deltaTime); // Actualiza el estado (time-based) void updateTimer(); // Actualiza el temporizador void disable(); // Deshabilita el objeto }; \ No newline at end of file