diff --git a/deltatime_cleanup_plan.md b/deltatime_cleanup_plan.md index 44b86bd..a8d8d77 100644 --- a/deltatime_cleanup_plan.md +++ b/deltatime_cleanup_plan.md @@ -31,6 +31,7 @@ - [ ] Buscar comentarios con "frame" o "60fps" - [ ] Localizar magic numbers y convertirlos a constantes con nombres descriptivos - [ ] **IMPORTANTE**: Modificar speed en ficheros .ani - está en frames, hay que pasarlo a milisegundos (multiplicar speed por 1000/60 = 16.67) +- [ ] **SmartSprite**: Revisar inicialización de SmartSprites en el código - cambiar setFinishedCounter() a setFinishedDelay() y convertir valores de frames a milisegundos ### 5. Cambio de Unidades de Tiempo en sections/* - [ ] Cambiar el cálculo de deltatime en source/sections/* para que devuelva segundos (float) en lugar de milisegundos diff --git a/source/background.cpp b/source/background.cpp index 95da3f2..372a622 100644 --- a/source/background.cpp +++ b/source/background.cpp @@ -138,8 +138,12 @@ void Background::update(float delta_time) { // Actualiza las nubes updateClouds(delta_time); - // Calcula el frame de la hierba - grass_sprite_->setSpriteClip(0, (10 * (counter_ / 20 % 2)), 320, 10); + // Actualiza timer de hierba + grass_timer_ += delta_time; + + // Calcula el frame de la hierba (alterna cada GRASS_FRAME_DURATION ms) + int grass_frame = static_cast(grass_timer_ / GRASS_FRAME_DURATION) % 2; + grass_sprite_->setSpriteClip(0, (10 * grass_frame), 320, 10); // Calcula el valor de alpha alpha_ = std::max((255 - (int)(255 * transition_)), 0); @@ -148,9 +152,6 @@ void Background::update(float delta_time) { sun_sprite_->setPosition(sun_path_.at(sun_index_)); moon_sprite_->setPosition(moon_path_.at(moon_index_)); - // Incrementa el contador - ++counter_; - // Compone todos los elementos del fondo en la textura fillCanvas(); } diff --git a/source/background.h b/source/background.h index f8b96ea..f2db18d 100644 --- a/source/background.h +++ b/source/background.h @@ -107,7 +107,8 @@ class Background { float clouds_speed_ = 0; // Velocidad de las nubes float transition_ = 0; // Porcentaje de transición size_t gradient_number_ = 0; // Índice de fondo degradado - size_t counter_ = 0; // Contador interno + float grass_timer_ = 0.0f; // Timer para animación de hierba (ms) + static constexpr float GRASS_FRAME_DURATION = 333.34f; // Duración por frame de hierba (20 frames * 16.67ms) size_t alpha_color_texture_ = 0; // Transparencia de atenuación size_t previous_alpha_color_texture_ = 0; // Transparencia anterior size_t sun_index_ = 0; // Índice del recorrido del sol diff --git a/source/game_logo.cpp b/source/game_logo.cpp index a8a1832..b832298 100644 --- a/source/game_logo.cpp +++ b/source/game_logo.cpp @@ -45,7 +45,7 @@ void GameLogo::init() { arcade_edition_status_ = Status::DISABLED; shake_.init(1, 2, 8, XP); zoom_ = 3.0F * ZOOM_FACTOR; - post_finished_time_accumulator_ = 0.0f; + post_finished_timer_ = 0.0f; // Inicializa el bitmap de 'Coffee' coffee_sprite_->setPosX(XP); @@ -58,7 +58,7 @@ void GameLogo::init() { coffee_sprite_->setAccelY(COFFEE_ACCEL_Y); coffee_sprite_->setSpriteClip(0, 0, coffee_texture_->getWidth(), coffee_texture_->getHeight()); coffee_sprite_->setEnabled(true); - coffee_sprite_->setFinishedCounter(0); + coffee_sprite_->setFinishedDelay(0.0f); coffee_sprite_->setDestX(XP); coffee_sprite_->setDestY(y_ - coffee_texture_->getHeight()); @@ -73,7 +73,7 @@ void GameLogo::init() { crisis_sprite_->setAccelY(CRISIS_ACCEL_Y); crisis_sprite_->setSpriteClip(0, 0, crisis_texture_->getWidth(), crisis_texture_->getHeight()); crisis_sprite_->setEnabled(true); - crisis_sprite_->setFinishedCounter(0); + crisis_sprite_->setFinishedDelay(0.0f); crisis_sprite_->setDestX(XP + CRISIS_OFFSET_X); crisis_sprite_->setDestY(y_); @@ -192,28 +192,12 @@ void GameLogo::handleArcadeEditionShaking(float deltaTime) { } } -void GameLogo::processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite) { - if (shake_.counter > 0) { - shake_.counter--; - } else { - shake_.counter = shake_.delay; - const auto DISPLACEMENT = calculateShakeDisplacement(); - primary_sprite->setPosX(shake_.origin + DISPLACEMENT); - if (secondary_sprite != nullptr) { - secondary_sprite->setPosX(shake_.origin + DISPLACEMENT + CRISIS_OFFSET_X); - } - shake_.remaining--; - } -} void GameLogo::processShakeEffect(SmartSprite* primary_sprite, SmartSprite* secondary_sprite, float deltaTime) { - // Delay fijo en milisegundos (shake_.delay era frames, ahora usamos constante) - float delayTime = SHAKE_DELAY_MS; - shake_.time_accumulator += deltaTime; - if (shake_.time_accumulator >= delayTime) { - shake_.time_accumulator -= delayTime; + if (shake_.time_accumulator >= SHAKE_DELAY_MS) { + shake_.time_accumulator -= SHAKE_DELAY_MS; const auto DISPLACEMENT = calculateShakeDisplacement(); primary_sprite->setPosX(shake_.origin + DISPLACEMENT); if (secondary_sprite != nullptr) { @@ -269,18 +253,9 @@ void GameLogo::updateDustSprites(float deltaTime) { void GameLogo::updatePostFinishedCounter(float deltaTime) { if (coffee_crisis_status_ == Status::FINISHED && - arcade_edition_status_ == Status::FINISHED && - post_finished_counter_ > 0) { - - // Tiempo entre decrementos del counter - float frameTime = POST_FINISHED_FRAME_TIME; - - post_finished_time_accumulator_ += deltaTime; - - if (post_finished_time_accumulator_ >= frameTime) { - post_finished_time_accumulator_ -= frameTime; - --post_finished_counter_; - } + arcade_edition_status_ == Status::FINISHED) { + + post_finished_timer_ += deltaTime; } } @@ -292,7 +267,7 @@ void GameLogo::enable() { // Indica si ha terminado la animación auto GameLogo::hasFinished() const -> bool { - return post_finished_counter_ == 0; + return post_finished_timer_ >= post_finished_delay_ms_; } // Calcula el desplazamiento vertical inicial diff --git a/source/game_logo.h b/source/game_logo.h index 0159d9e..576ec35 100644 --- a/source/game_logo.h +++ b/source/game_logo.h @@ -92,8 +92,8 @@ class GameLogo { float x_; // Posición X del logo float y_; // Posición Y del logo float zoom_ = 1.0F; // Zoom aplicado al texto "ARCADE EDITION" - int post_finished_counter_ = 1; // Contador final tras animaciones (frame-based) - float post_finished_time_accumulator_ = 0.0f; // Acumulador de tiempo para post_finished_counter + float post_finished_delay_ms_ = POST_FINISHED_FRAME_TIME; // Retraso final tras animaciones (ms) + float post_finished_timer_ = 0.0f; // Timer acumulado para retraso final (ms) // --- Inicialización --- void init(); // Inicializa las variables diff --git a/source/smart_sprite.cpp b/source/smart_sprite.cpp index 1118067..d9d4f0f 100644 --- a/source/smart_sprite.cpp +++ b/source/smart_sprite.cpp @@ -7,7 +7,7 @@ void SmartSprite::update(float deltaTime) { if (enabled_) { MovingSprite::update(deltaTime); checkMove(); - checkFinished(); + checkFinished(deltaTime); } } @@ -71,16 +71,19 @@ void SmartSprite::checkMove() { } } -// Comprueba si ha terminado -void SmartSprite::checkFinished() { +// Comprueba si ha terminado (time-based) +void SmartSprite::checkFinished(float deltaTime) { // Comprueba si ha llegado a su destino on_destination_ = (getPosX() == dest_x_ && getPosY() == dest_y_); if (on_destination_) { - if (finished_counter_ == 0) { + if (finished_delay_ms_ == 0.0f) { finished_ = true; } else { - --finished_counter_; + finished_timer_ += deltaTime; + if (finished_timer_ >= finished_delay_ms_) { + finished_ = true; + } } } } \ No newline at end of file diff --git a/source/smart_sprite.h b/source/smart_sprite.h index d367856..0b0d26f 100644 --- a/source/smart_sprite.h +++ b/source/smart_sprite.h @@ -26,21 +26,22 @@ class SmartSprite : public AnimatedSprite { auto hasFinished() const -> bool { return finished_; } // Indica si ya ha terminado // --- Setters --- - void setFinishedCounter(int value) { finished_counter_ = value; } // Establece el contador para deshabilitarlo - void setDestX(int x) { dest_x_ = x; } // Establece la posición de destino en X - void setDestY(int y) { dest_y_ = y; } // Establece la posición de destino en Y - void setEnabled(bool value) { enabled_ = value; } // Habilita o deshabilita el objeto + void setFinishedDelay(float value) { finished_delay_ms_ = value; } // Establece el retraso para deshabilitarlo (ms) + void setDestX(int x) { dest_x_ = x; } // Establece la posición de destino en X + void setDestY(int y) { dest_y_ = y; } // Establece la posición de destino en Y + void setEnabled(bool value) { enabled_ = value; } // Habilita o deshabilita el objeto private: // --- Variables de estado --- - int dest_x_ = 0; // Posición de destino en el eje X - int dest_y_ = 0; // Posición de destino en el eje Y - int finished_counter_ = 0; // Contador para deshabilitarlo + int dest_x_ = 0; // Posición de destino en el eje X + int dest_y_ = 0; // Posición de destino en el eje Y + float finished_delay_ms_ = 0.0f; // Retraso para deshabilitarlo (ms) + float finished_timer_ = 0.0f; // Timer acumulado (ms) bool on_destination_ = false; // Indica si está en el destino bool finished_ = false; // Indica si ya ha terminado bool enabled_ = false; // Indica si el objeto está habilitado // --- Métodos internos --- - void checkFinished(); // Comprueba si ha terminado - void checkMove(); // Comprueba el movimiento + void checkFinished(float deltaTime); // Comprueba si ha terminado (time-based) + void checkMove(); // Comprueba el movimiento }; \ No newline at end of file diff --git a/source/tiled_bg.cpp b/source/tiled_bg.cpp index d5547fd..1935c8e 100644 --- a/source/tiled_bg.cpp +++ b/source/tiled_bg.cpp @@ -81,32 +81,6 @@ void TiledBG::render() { SDL_RenderTexture(renderer_, canvas_, &window_, &pos_); } -// Actualiza la lógica de la clase (frame-based) -void TiledBG::update() { - updateDesp(); - updateStop(); - - switch (mode_) { - case TiledBGMode::DIAGONAL: { - // El tileado de fondo se desplaza en diagonal - window_.x = static_cast(desp_) % TILE_WIDTH; - window_.y = static_cast(desp_) % TILE_HEIGHT; - - break; - } - case TiledBGMode::CIRCLE: { - // El tileado de fondo se desplaza en circulo - const int INDEX = static_cast(desp_) % 360; - - window_.x = 128 + (static_cast(sin_[(INDEX + 270) % 360] * 128)); - window_.y = 128 + (static_cast(sin_[(360 - INDEX) % 360] * 96)); - break; - } - default: - break; - } -} - // Actualiza la lógica de la clase (time-based) void TiledBG::update(float delta_time) { updateDesp(delta_time); @@ -133,40 +107,20 @@ void TiledBG::update(float delta_time) { } } -// Detiene el desplazamiento de forma ordenada (frame-based) -void TiledBG::updateStop() { - if (stopping_) { - const int UMBRAL = 20 * speed_; // Ajusta este valor según la precisión deseada - - // Desacelerar si estamos cerca de completar el ciclo (ventana a punto de regresar a 0) - if (window_.x >= TILE_WIDTH - UMBRAL) { - speed_ /= 1.05F; // Reduce gradualmente la velocidad - - // Asegura que no baje demasiado - speed_ = std::max(speed_, 0.1F); - } - - // Si estamos en 0, detener - if (window_.x == 0) { - speed_ = 0.0F; - stopping_ = false; // Desactivamos el estado de "stopping" - } - } -} - // Detiene el desplazamiento de forma ordenada (time-based) void TiledBG::updateStop(float delta_time) { if (stopping_) { - const int UMBRAL = 20 * speed_; // Ajusta este valor según la precisión deseada + const int UMBRAL = STOP_THRESHOLD_FACTOR * speed_; // Desacelerar si estamos cerca de completar el ciclo (ventana a punto de regresar a 0) if (window_.x >= TILE_WIDTH - UMBRAL) { - // Convertir 1.05F por frame a por milisegundo: (1.05^(60*delta_time/1000)) - float deceleration_factor = std::pow(1.05F, 60.0F * delta_time / 1000.0F); - speed_ /= deceleration_factor; + // Aplicar desaceleración time-based + float frame_rate = 60.0F; + float deceleration_per_ms = std::pow(DECELERATION_FACTOR, frame_rate * delta_time / 1000.0F); + speed_ /= deceleration_per_ms; // Asegura que no baje demasiado - speed_ = std::max(speed_, 0.1F); + speed_ = std::max(speed_, MIN_SPEED); } // Si estamos en 0, detener diff --git a/source/tiled_bg.h b/source/tiled_bg.h index c33d5a1..99cd876 100644 --- a/source/tiled_bg.h +++ b/source/tiled_bg.h @@ -24,9 +24,8 @@ class TiledBG { ~TiledBG(); // --- Métodos principales --- - void render(); // Pinta la clase en pantalla - void update(); // Actualiza la lógica de la clase (compatibilidad) - void update(float delta_time); // Actualiza la lógica de la clase + void render(); // Pinta la clase en pantalla + void update(float delta_time); // Actualiza la lógica de la clase // --- Configuración --- void setSpeed(float speed) { speed_ = speed; } // Establece la velocidad @@ -38,8 +37,11 @@ class TiledBG { private: // --- Constantes --- - static constexpr int TILE_WIDTH = 64; // Ancho del tile - static constexpr int TILE_HEIGHT = 64; // Alto del tile + static constexpr int TILE_WIDTH = 64; // Ancho del tile + static constexpr int TILE_HEIGHT = 64; // Alto del tile + static constexpr float STOP_THRESHOLD_FACTOR = 20.0f; // Factor para umbral de parada + static constexpr float DECELERATION_FACTOR = 1.05f; // Factor de desaceleración + static constexpr float MIN_SPEED = 0.1f; // Velocidad mínima // --- Objetos y punteros --- SDL_Renderer *renderer_; // El renderizador de la ventana @@ -55,9 +57,7 @@ class TiledBG { bool stopping_ = false; // Indica si se está deteniendo // --- Métodos internos --- - void fillTexture(); // Rellena la textura con el contenido - void updateDesp() { desp_ += speed_; } // Actualiza el desplazamiento (frame-based) - void updateDesp(float delta_time) { desp_ += speed_ * delta_time / (1000.0f / 60.0f); } // Actualiza el desplazamiento (time-based) - void updateStop(); // Detiene el desplazamiento de forma ordenada (frame-based) - void updateStop(float delta_time); // Detiene el desplazamiento de forma ordenada (time-based) + void fillTexture(); // Rellena la textura con el contenido + void updateDesp(float delta_time) { desp_ += speed_ * delta_time; } // Actualiza el desplazamiento (time-based) + void updateStop(float delta_time); // Detiene el desplazamiento de forma ordenada (time-based) }; \ No newline at end of file