diff --git a/source/balloon.cpp b/source/balloon.cpp index e982ba1..622e1fe 100644 --- a/source/balloon.cpp +++ b/source/balloon.cpp @@ -135,7 +135,7 @@ void Balloon::render() { } } -// Actualiza la posición y estados del globo +// Actualiza la posición y estados del globo (frame-based) void Balloon::move() { if (isStopped()) { return; @@ -146,6 +146,17 @@ void Balloon::move() { applyGravity(); } +// Actualiza la posición y estados del globo (time-based) +void Balloon::move(float deltaTime) { + if (isStopped()) { + return; + } + + handleHorizontalMovement(deltaTime); + handleVerticalMovement(deltaTime); + applyGravity(deltaTime); +} + void Balloon::handleHorizontalMovement() { x_ += vx_ * speed_; @@ -158,6 +169,20 @@ void Balloon::handleHorizontalMovement() { } } +void Balloon::handleHorizontalMovement(float deltaTime) { + // Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps) + float frameFactor = deltaTime / (1000.0f / 60.0f); + x_ += vx_ * speed_ * frameFactor; + + const int CLIP = 2; + const float MIN_X = play_area_.x - CLIP; + const float MAX_X = play_area_.x + play_area_.w - w_ + CLIP; + + if (isOutOfHorizontalBounds(MIN_X, MAX_X)) { + handleHorizontalBounce(MIN_X, MAX_X); + } +} + void Balloon::handleVerticalMovement() { y_ += vy_ * speed_; @@ -168,6 +193,18 @@ void Balloon::handleVerticalMovement() { handleBottomCollision(); } +void Balloon::handleVerticalMovement(float deltaTime) { + // Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps) + float frameFactor = deltaTime / (1000.0f / 60.0f); + y_ += vy_ * speed_ * frameFactor; + + if (shouldCheckTopCollision()) { + handleTopCollision(); + } + + handleBottomCollision(); +} + auto Balloon::isOutOfHorizontalBounds(float min_x, float max_x) const -> bool { return x_ < min_x || x_ > max_x; } @@ -230,6 +267,18 @@ void Balloon::applyGravity() { } } +void Balloon::applyGravity(float deltaTime) { + // Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps) + float frameFactor = deltaTime / (1000.0f / 60.0f); + + travel_y_ += speed_ * frameFactor; + + if (travel_y_ >= 1.0F) { + travel_y_ -= 1.0F; + vy_ += gravity_; + } +} + void Balloon::playBouncingSound() { if (sound_.enabled && sound_.bouncing_enabled) { Audio::get()->playSound(sound_.bouncing_file); @@ -242,7 +291,7 @@ void Balloon::playPoppingSound() { } } -// Actualiza al globo a su posicion, animación y controla los contadores +// Actualiza al globo a su posicion, animación y controla los contadores (frame-based) void Balloon::update() { move(); updateState(); @@ -253,7 +302,20 @@ void Balloon::update() { ++counter_; } -// Actualiza los estados del globo +// Actualiza al globo a su posicion, animación y controla los contadores (time-based) +void Balloon::update(float deltaTime) { + move(deltaTime); + updateState(deltaTime); + updateBounceEffect(); + shiftSprite(); + shiftColliders(); + sprite_->update(deltaTime); + // Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps) + float frameFactor = deltaTime / (1000.0f / 60.0f); + counter_ += frameFactor; +} + +// Actualiza los estados del globo (frame-based) void Balloon::updateState() { // Si se está creando if (isBeingCreated()) { @@ -263,7 +325,7 @@ void Balloon::updateState() { if (creation_counter_ > 0) { // Desplaza lentamente el globo hacia abajo y hacia un lado - if (creation_counter_ % 10 == 0) { + if (static_cast(creation_counter_) % 10 == 0) { y_++; x_ += vx_; @@ -290,6 +352,51 @@ void Balloon::updateState() { } } +// Actualiza los estados del globo (time-based) +void Balloon::updateState(float deltaTime) { + // Si se está creando + if (isBeingCreated()) { + // Actualiza el valor de las variables + stop(); + setInvulnerable(true); + + if (creation_counter_ > 0) { + // Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps) + float frameFactor = deltaTime / (1000.0f / 60.0f); + + // Desplaza lentamente el globo hacia abajo y hacia un lado + // Cada 10 frames (aproximadamente cada 166ms a 60fps) + movement_accumulator_ += frameFactor; + + if (movement_accumulator_ >= 10.0f) { + movement_accumulator_ -= 10.0f; + y_++; + x_ += vx_; + + // Comprueba no se salga por los laterales + const int MIN_X = play_area_.x; + const int MAX_X = play_area_.w - w_; + + if (x_ < MIN_X || x_ > MAX_X) { + // Corrige y cambia el sentido de la velocidad + x_ -= vx_; + vx_ = -vx_; + } + } + creation_counter_ -= frameFactor; + if (creation_counter_ < 0) creation_counter_ = 0; + } + + else { + // El contador ha llegado a cero + being_created_ = false; + start(); + setInvulnerable(false); + setAnimation(); + } + } +} + // Establece la animación correspondiente al estado void Balloon::setAnimation() { std::string creating_animation; diff --git a/source/balloon.h b/source/balloon.h index 96af872..7663d86 100644 --- a/source/balloon.h +++ b/source/balloon.h @@ -87,11 +87,13 @@ class Balloon { ~Balloon() = default; // --- Métodos principales --- - void alignTo(int x); // Centra el globo en la posición X - void render(); // Pinta el globo en la pantalla - void move(); // Actualiza la posición y estados del globo - void update(); // Actualiza el globo (posición, animación, contadores) - void stop(); // Detiene el globo + void alignTo(int x); // Centra el globo en la posición X + void render(); // Pinta el globo en la pantalla + void move(); // Actualiza la posición y estados del globo (frame-based) + void move(float deltaTime); // Actualiza la posición y estados del globo (time-based) + void update(); // Actualiza el globo (posición, animación, contadores) (frame-based) + void update(float deltaTime); // Actualiza el globo (posición, animación, contadores) (time-based) + void stop(); // Detiene el globo void start(); // Pone el globo en movimiento void pop(bool should_sound = false); // Explota el globo @@ -256,8 +258,8 @@ class Balloon { bool stopped_; // Si el globo está parado bool use_reversed_colors_ = false; // Si se usa el color alternativo Circle collider_; // Círculo de colisión - Uint16 creation_counter_; // Temporizador de creación - Uint16 creation_counter_ini_; // Valor inicial del temporizador de creación + float creation_counter_; // Temporizador de creación + float creation_counter_ini_; // Valor inicial del temporizador de creación Uint16 score_; // Puntos al destruir el globo Type type_; // Tipo de globo Size size_; // Tamaño de globo @@ -265,6 +267,7 @@ class Balloon { Uint32 counter_ = 0; // Contador interno float travel_y_ = 1.0F; // Distancia a recorrer en Y antes de aplicar gravedad float speed_; // Velocidad del globo + float movement_accumulator_ = 0.0f; // Acumulador para movimiento durante creación (deltaTime) Uint8 power_; // Poder que alberga el globo SDL_FRect play_area_; // Zona de movimiento del globo Sound sound_; // Configuración de sonido del globo @@ -280,9 +283,12 @@ class Balloon { void playPoppingSound(); // Reproduce el sonido de reventar // --- Movimiento y física --- - void handleHorizontalMovement(); // Maneja el movimiento horizontal - void handleVerticalMovement(); // Maneja el movimiento vertical - void applyGravity(); // Aplica la gravedad al objeto + void handleHorizontalMovement(); // Maneja el movimiento horizontal (frame-based) + void handleHorizontalMovement(float deltaTime); // Maneja el movimiento horizontal (time-based) + void handleVerticalMovement(); // Maneja el movimiento vertical (frame-based) + void handleVerticalMovement(float deltaTime); // Maneja el movimiento vertical (time-based) + void applyGravity(); // Aplica la gravedad al objeto (frame-based) + void applyGravity(float deltaTime); // Aplica la gravedad al objeto (time-based) // --- Rebote --- void enableBounceEffect(); // Activa el efecto de rebote @@ -297,5 +303,6 @@ class Balloon { void handleBottomCollision(); // Maneja la colisión inferior // --- Lógica de estado --- - void updateState(); // Actualiza los estados del globo + void updateState(); // Actualiza los estados del globo (frame-based) + void updateState(float deltaTime); // Actualiza los estados del globo (time-based) }; \ No newline at end of file diff --git a/source/balloon_manager.cpp b/source/balloon_manager.cpp index 846eaa9..0dc84f1 100644 --- a/source/balloon_manager.cpp +++ b/source/balloon_manager.cpp @@ -62,7 +62,7 @@ void BalloonManager::init() { explosions_->addTexture(3, explosions_textures_.at(3), explosions_animations_.at(3)); } -// Actualiza +// Actualiza (frame-based) void BalloonManager::update() { for (const auto &balloon : balloons_) { balloon->update(); @@ -71,6 +71,15 @@ void BalloonManager::update() { explosions_->update(); } +// Actualiza (time-based) +void BalloonManager::update(float deltaTime) { + for (const auto &balloon : balloons_) { + balloon->update(deltaTime); + } + updateBalloonDeployCounter(deltaTime); + explosions_->update(); // Explosions aún no migrado a deltaTime +} + // Renderiza los objetos void BalloonManager::render() { for (auto &balloon : balloons_) { @@ -162,13 +171,23 @@ void BalloonManager::freeBalloons() { balloons_.erase(result.begin(), balloons_.end()); } -// Actualiza la variable enemyDeployCounter +// Actualiza la variable enemyDeployCounter (frame-based) void BalloonManager::updateBalloonDeployCounter() { if (balloon_deploy_counter_ > 0) { --balloon_deploy_counter_; } } +// Actualiza la variable enemyDeployCounter (time-based) +void BalloonManager::updateBalloonDeployCounter(float deltaTime) { + if (balloon_deploy_counter_ > 0) { + // Convertir deltaTime (milisegundos) a factor de frame (asumiendo 60fps) + float frameFactor = deltaTime / (1000.0f / 60.0f); + balloon_deploy_counter_ -= frameFactor; + if (balloon_deploy_counter_ < 0) balloon_deploy_counter_ = 0; + } +} + // Indica si se puede crear una powerball auto BalloonManager::canPowerBallBeCreated() -> bool { return (!power_ball_enabled_) && (calculateScreenPower() > Balloon::POWERBALL_SCREENPOWER_MINIMUM) && (power_ball_counter_ == 0); } diff --git a/source/balloon_manager.h b/source/balloon_manager.h index 6458e6a..83ad3fb 100644 --- a/source/balloon_manager.h +++ b/source/balloon_manager.h @@ -28,8 +28,9 @@ class BalloonManager { ~BalloonManager() = default; // --- Métodos principales --- - void update(); // Actualiza el estado de los globos - void render(); // Renderiza los globos en pantalla + void update(); // Actualiza el estado de los globos (frame-based) + void update(float deltaTime); // Actualiza el estado de los globos (time-based) + void render(); // Renderiza los globos en pantalla // --- Gestión de globos --- void freeBalloons(); // Libera globos que ya no sirven @@ -49,7 +50,8 @@ class BalloonManager { void setBalloonSpeed(float speed); // Ajusta la velocidad de los globos void setDefaultBalloonSpeed(float speed) { default_balloon_speed_ = speed; }; // Establece la velocidad base void resetBalloonSpeed() { setBalloonSpeed(default_balloon_speed_); }; // Restablece la velocidad de los globos - void updateBalloonDeployCounter(); // Actualiza el contador de despliegue + void updateBalloonDeployCounter(); // Actualiza el contador de despliegue (frame-based) + void updateBalloonDeployCounter(float deltaTime); // Actualiza el contador de despliegue (time-based) auto canPowerBallBeCreated() -> bool; // Indica si se puede crear una PowerBall auto calculateScreenPower() -> int; // Calcula el poder de los globos en pantalla @@ -98,7 +100,7 @@ class BalloonManager { SDL_FRect play_area_ = param.game.play_area.rect; float balloon_speed_ = Balloon::SPEED.at(0); float default_balloon_speed_ = Balloon::SPEED.at(0); - int balloon_deploy_counter_ = 0; + float balloon_deploy_counter_ = 0; int power_ball_counter_ = 0; int last_balloon_deploy_ = 0; bool power_ball_enabled_ = false; diff --git a/source/director.cpp b/source/director.cpp index 3dc6a53..7b8ea00 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -42,7 +42,7 @@ Director::Director(int argc, std::span argv) { Section::name = Section::Name::GAME; Section::options = Section::Options::GAME_PLAY_1P; #elif _DEBUG - Section::name = Section::Name::LOGO; + Section::name = Section::Name::CREDITS; Section::options = Section::Options::GAME_PLAY_1P; #else // NORMAL GAME Section::name = Section::Name::LOGO; diff --git a/source/sections/credits.cpp b/source/sections/credits.cpp index 900d1c0..1248cf0 100644 --- a/source/sections/credits.cpp +++ b/source/sections/credits.cpp @@ -78,20 +78,31 @@ Credits::~Credits() { Options::gamepad_manager.clearPlayers(); } +// Calcula el deltatime +auto Credits::calculateDeltaTime() -> float { + const Uint64 current_time = SDL_GetTicks(); + const float delta_time = static_cast(current_time - last_time_); + last_time_ = current_time; + return delta_time; +} + // Bucle principal void Credits::run() { + last_time_ = SDL_GetTicks(); + while (Section::name == Section::Name::CREDITS) { checkInput(); - update(); + const float delta_time = calculateDeltaTime(); + update(delta_time); checkEvents(); // Tiene que ir antes del render render(); } } -// Actualiza las variables +// Actualiza las variables (frame-based) void Credits::update() { - if (SDL_GetTicks() - ticks_ > param.game.speed) { - ticks_ = SDL_GetTicks(); + if (SDL_GetTicks() - last_time_ > param.game.speed) { + last_time_ = SDL_GetTicks(); const int REPEAT = want_to_pass_ ? 4 : 1; for (int i = 0; i < REPEAT; ++i) { tiled_bg_->update(); @@ -111,6 +122,28 @@ void Credits::update() { Audio::update(); } +// Actualiza las variables (time-based) +void Credits::update(float deltaTime) { + const float multiplier = want_to_pass_ ? 4.0f : 1.0f; + const float adjusted_delta_time = deltaTime * multiplier; + + tiled_bg_->update(adjusted_delta_time); + cycleColors(); + balloon_manager_->update(adjusted_delta_time); + updateTextureDstRects(adjusted_delta_time); + throwBalloons(adjusted_delta_time); + updatePlayers(adjusted_delta_time); + updateAllFades(adjusted_delta_time); + + // Convertir deltaTime a factor de frame (asumiendo 60fps) + const float frameFactor = adjusted_delta_time / (1000.0f / 60.0f); + counter_ += frameFactor; + + Screen::get()->update(); + fillCanvas(); + Audio::update(); +} + // Dibuja Credits::en patalla void Credits::render() { static auto *const SCREEN = Screen::get(); @@ -277,9 +310,9 @@ void Credits::fillCanvas() { SDL_SetRenderTarget(Screen::get()->getRenderer(), temp); } -// Actualiza el destino de los rectangulos de las texturas +// Actualiza el destino de los rectangulos de las texturas (frame-based) void Credits::updateTextureDstRects() { - if (counter_ % 10 == 0) { + if (static_cast(counter_) % 10 == 0) { // Comprueba la posición de la textura con los titulos de credito if (credits_rect_dst_.y + credits_rect_dst_.h > play_area_.y) { --credits_rect_dst_.y; @@ -306,7 +339,42 @@ void Credits::updateTextureDstRects() { } } -// Tira globos al escenario +// Actualiza el destino de los rectangulos de las texturas (time-based) +void Credits::updateTextureDstRects(float deltaTime) { + constexpr float TEXTURE_UPDATE_INTERVAL = 10 * (1000.0f / 60.0f); // 166.67ms (cada 10 frames) + static float texture_accumulator = 0.0f; + texture_accumulator += deltaTime; + + if (texture_accumulator >= TEXTURE_UPDATE_INTERVAL) { + texture_accumulator -= TEXTURE_UPDATE_INTERVAL; + + // Comprueba la posición de la textura con los titulos de credito + if (credits_rect_dst_.y + credits_rect_dst_.h > play_area_.y) { + --credits_rect_dst_.y; + } + + // Comprueba la posición de la textura con el mini_logo + if (mini_logo_rect_dst_.y == mini_logo_final_pos_) { + mini_logo_on_position_ = true; + + // Si el jugador quiere pasar los titulos de credito, el fade se inicia solo + if (want_to_pass_) { + fading_ = true; + } + + // Se activa el contador para evitar que la sección sea infinita + if (counter_prevent_endless_ == 1000) { + fading_ = true; + } else { + ++counter_prevent_endless_; + } + } else { + --mini_logo_rect_dst_.y; + } + } +} + +// Tira globos al escenario (frame-based) void Credits::throwBalloons() { constexpr int SPEED = 200; const std::vector SETS = {0, 63, 25, 67, 17, 75, 13, 50}; @@ -315,12 +383,41 @@ void Credits::throwBalloons() { return; } - if (counter_ % SPEED == 0) { - const int INDEX = (counter_ / SPEED) % SETS.size(); + if (static_cast(counter_) % SPEED == 0) { + const int INDEX = (static_cast(counter_) / SPEED) % SETS.size(); balloon_manager_->deployFormation(SETS.at(INDEX), -60); } - if (counter_ % (SPEED * 4) == 0 && counter_ > 0) { + if (static_cast(counter_) % (SPEED * 4) == 0 && counter_ > 0) { + balloon_manager_->createPowerBall(); + } +} + +// Tira globos al escenario (time-based) +void Credits::throwBalloons(float deltaTime) { + constexpr int SPEED = 200; + const std::vector SETS = {0, 63, 25, 67, 17, 75, 13, 50}; + constexpr float BALLOON_INTERVAL = SPEED * (1000.0f / 60.0f); // 3333.33ms (cada 200 frames) + constexpr float POWERBALL_INTERVAL = (SPEED * 4) * (1000.0f / 60.0f); // 13333.33ms (cada 800 frames) + + if (counter_ > ((SETS.size() - 1) * SPEED) * 3) { + return; + } + + static float balloon_accumulator = 0.0f; + static float powerball_accumulator = 0.0f; + + balloon_accumulator += deltaTime; + powerball_accumulator += deltaTime; + + if (balloon_accumulator >= BALLOON_INTERVAL) { + balloon_accumulator -= BALLOON_INTERVAL; + const int INDEX = (static_cast(counter_ / SPEED)) % SETS.size(); + balloon_manager_->deployFormation(SETS.at(INDEX), -60); + } + + if (powerball_accumulator >= POWERBALL_INTERVAL && counter_ > 0) { + powerball_accumulator -= POWERBALL_INTERVAL; balloon_manager_->createPowerBall(); } } @@ -392,12 +489,12 @@ void Credits::initPlayers() { } } -// Actualiza los rectangulos negros +// Actualiza los rectangulos negros (frame-based) void Credits::updateBlackRects() { static int current_step_ = steps_; if (top_black_rect_.h != param.game.game_area.center_y - 1 && bottom_black_rect_.y != param.game.game_area.center_y + 1) { // Si los rectangulos superior e inferior no han llegado al centro - if (counter_ % 4 == 0) { + if (static_cast(counter_) % 4 == 0) { // Incrementa la altura del rectangulo superior top_black_rect_.h = std::min(top_black_rect_.h + 1, param.game.game_area.center_y - 1); @@ -435,6 +532,57 @@ void Credits::updateBlackRects() { } } +// Actualiza los rectangulos negros (time-based) +void Credits::updateBlackRects(float deltaTime) { + static float current_step_ = static_cast(steps_); + constexpr float BLACK_RECT_INTERVAL = 4 * (1000.0f / 60.0f); // 66.67ms (cada 4 frames) + static float black_rect_accumulator = 0.0f; + + if (top_black_rect_.h != param.game.game_area.center_y - 1 && bottom_black_rect_.y != param.game.game_area.center_y + 1) { + // Si los rectangulos superior e inferior no han llegado al centro + black_rect_accumulator += deltaTime; + if (black_rect_accumulator >= BLACK_RECT_INTERVAL) { + black_rect_accumulator -= BLACK_RECT_INTERVAL; + + // Incrementa la altura del rectangulo superior + top_black_rect_.h = std::min(top_black_rect_.h + 1, param.game.game_area.center_y - 1); + + // Incrementa la altura y modifica la posición del rectangulo inferior + ++bottom_black_rect_.h; + bottom_black_rect_.y = std::max(bottom_black_rect_.y - 1, param.game.game_area.center_y + 1); + + --current_step_; + setVolume(static_cast(initial_volume_ * current_step_ / steps_)); + } + } else { + // Si los rectangulos superior e inferior han llegado al centro + if (left_black_rect_.w != param.game.game_area.center_x && right_black_rect_.x != param.game.game_area.center_x) { + constexpr int SPEED = 2; + // Si los rectangulos izquierdo y derecho no han llegado al centro + // Incrementa la anchura del rectangulo situado a la izquierda + left_black_rect_.w = std::min(left_black_rect_.w + SPEED, param.game.game_area.center_x); + + // Incrementa la anchura y modifica la posición del rectangulo situado a la derecha + right_black_rect_.w += SPEED; + right_black_rect_.x = std::max(right_black_rect_.x - SPEED, param.game.game_area.center_x); + + --current_step_; + setVolume(static_cast(initial_volume_ * current_step_ / steps_)); + } else { + // Si los rectangulos izquierdo y derecho han llegado al centro + setVolume(0); + Audio::get()->stopMusic(); + if (counter_pre_fade_ == 400) { + fade_out_->activate(); + } else { + // Convertir deltaTime a factor de frame + const float frameFactor = deltaTime / (1000.0f / 60.0f); + counter_pre_fade_ += frameFactor; + } + } + } +} + // Actualiza el rectangulo rojo void Credits::updateRedRect() { border_rect_.x = left_black_rect_.x + left_black_rect_.w; @@ -443,7 +591,7 @@ void Credits::updateRedRect() { border_rect_.h = bottom_black_rect_.y - border_rect_.y + 1; } -// Actualiza el estado de fade +// Actualiza el estado de fade (frame-based) void Credits::updateAllFades() { if (fading_) { updateBlackRects(); @@ -461,6 +609,24 @@ void Credits::updateAllFades() { } } +// Actualiza el estado de fade (time-based) +void Credits::updateAllFades(float deltaTime) { + if (fading_) { + updateBlackRects(deltaTime); + updateRedRect(); + } + + fade_in_->update(); // Fade aún no migrado a deltaTime + if (fade_in_->hasEnded()) { + Audio::get()->playMusic("credits.ogg"); + } + + fade_out_->update(); // Fade aún no migrado a deltaTime + if (fade_out_->hasEnded()) { + Section::name = Section::Name::HI_SCORE_TABLE; + } +} + // Establece el nivel de volumen void Credits::setVolume(int amount) { Options::audio.music.volume = std::clamp(amount, 0, 100); @@ -508,13 +674,20 @@ void Credits::cycleColors() { tiled_bg_->setColor(color_); } -// Actualza los jugadores +// Actualza los jugadores (frame-based) void Credits::updatePlayers() { for (auto &player : players_) { player->update(); } } +// Actualza los jugadores (time-based) +void Credits::updatePlayers(float deltaTime) { + for (auto &player : players_) { + player->update(deltaTime); + } +} + // Renderiza los jugadores void Credits::renderPlayers() { for (auto const &player : players_) { diff --git a/source/sections/credits.h b/source/sections/credits.h index 87ea31e..d6bf4ab 100644 --- a/source/sections/credits.h +++ b/source/sections/credits.h @@ -25,6 +25,12 @@ class Credits { // --- Bucle principal --- void run(); + private: + // --- Métodos del bucle principal --- + void update(); // Actualización principal de la lógica (frame-based) + void update(float deltaTime); // Actualización principal de la lógica (time-based) + auto calculateDeltaTime() -> float; // Calcula el deltatime + private: // --- Constantes de clase --- static constexpr int PLAY_AREA_HEIGHT = 200; @@ -41,10 +47,10 @@ class Credits { SDL_Texture *canvas_; // Textura donde se dibuja todo // --- Temporización y contadores --- - Uint64 ticks_ = 0; // Control de velocidad del programa - Uint32 counter_ = 0; // Contador principal de lógica - Uint32 counter_pre_fade_ = 0; // Activación del fundido final - Uint32 counter_prevent_endless_ = 0; // Prevención de bucle infinito + Uint64 last_time_ = 0; // Último tiempo registrado para deltaTime + float counter_ = 0; // Contador principal de lógica + float counter_pre_fade_ = 0; // Activación del fundido final + float counter_prevent_endless_ = 0; // Prevención de bucle infinito // --- Variables de estado --- bool fading_ = false; // Estado del fade final @@ -101,8 +107,6 @@ class Credits { // Borde para la ventana SDL_FRect border_rect_ = play_area_; // Delimitador de ventana - // --- Métodos del bucle principal --- - void update(); // Actualización principal de la lógica void render(); // Renderizado de la escena static void checkEvents(); // Manejo de eventos void checkInput(); // Procesamiento de entrada @@ -110,19 +114,24 @@ class Credits { // --- Métodos de renderizado --- void fillTextTexture(); // Crear textura de texto de créditos void fillCanvas(); // Renderizar todos los sprites y fondos - void updateTextureDstRects(); // Actualizar destinos de texturas void renderPlayers(); // Renderiza los jugadores // --- Métodos de lógica del juego --- - void throwBalloons(); // Lanzar globos al escenario - void initPlayers(); // Inicializar jugadores - void updateAllFades(); // Actualizar estados de fade - void cycleColors(); // Cambiar colores de fondo - void updatePlayers(); // Actualza los jugadores + void throwBalloons(); // Lanzar globos al escenario (frame-based) + void throwBalloons(float deltaTime); // Lanzar globos al escenario (time-based) + void initPlayers(); // Inicializar jugadores + void updateAllFades(); // Actualizar estados de fade (frame-based) + void updateAllFades(float deltaTime); // Actualizar estados de fade (time-based) + void cycleColors(); // Cambiar colores de fondo + void updatePlayers(); // Actualza los jugadores (frame-based) + void updatePlayers(float deltaTime); // Actualza los jugadores (time-based) // --- Métodos de interfaz --- - void updateBlackRects(); // Actualizar rectángulos negros (letterbox) - void updateRedRect(); // Actualizar rectángulo rojo (borde) + void updateBlackRects(); // Actualizar rectángulos negros (letterbox) (frame-based) + void updateBlackRects(float deltaTime); // Actualizar rectángulos negros (letterbox) (time-based) + void updateRedRect(); // Actualizar rectángulo rojo (borde) + void updateTextureDstRects(); // Actualizar destinos de texturas (frame-based) + void updateTextureDstRects(float deltaTime); // Actualizar destinos de texturas (time-based) // --- Métodos de audio --- static void setVolume(int amount); // Establecer volumen