corregit en background.cpp la desaceleració final, millorada amb funció de suavitzat i arreglades les velocitats dels nuvols que no variaven amb el pas del joc

This commit is contained in:
2025-09-24 21:54:38 +02:00
parent 987dcd0205
commit 308f5c20fb
2 changed files with 96 additions and 66 deletions

View File

@@ -13,6 +13,7 @@
#include "screen.h" // Para Screen
#include "sprite.h" // Para Sprite
#include "texture.h" // Para Texture
#include "utils.h" // Para funciones de easing
// Constructor
Background::Background(float total_progress_to_complete)
@@ -29,6 +30,7 @@ Background::Background(float total_progress_to_complete)
total_progress_to_complete_(total_progress_to_complete),
progress_per_stage_(total_progress_to_complete_ / STAGES),
sun_completion_progress_(total_progress_to_complete_ * SUN_COMPLETION_FACTOR),
minimum_completed_progress_(total_progress_to_complete_ * MINIMUM_COMPLETED_PROGRESS_PERCENTAGE),
rect_(SDL_FRect{0, 0, static_cast<float>(gradients_texture_->getWidth() / 2), static_cast<float>(gradients_texture_->getHeight() / 2)}),
src_rect_({.x = 0, .y = 0, .w = 320, .h = 240}),
@@ -93,20 +95,21 @@ void Background::initializeSprites() {
// Configura las propiedades iniciales de los sprites
void Background::initializeSpriteProperties() {
constexpr float TOP_CLOUDS_SPEED = 0.1F;
constexpr float BOTTOM_CLOUDS_SPEED = 0.05F;
// Velocidades iniciales que coinciden con updateCloudsSpeed() cuando progress=0
constexpr float INITIAL_TOP_CLOUDS_SPEED_PX_PER_S = 0.05F * 60.0F; // 3.0 píxeles/segundo (coincide con CLOUDS_INITIAL_SPEED)
constexpr float INITIAL_BOTTOM_CLOUDS_SPEED_PX_PER_S = 0.05F * 60.0F / 2.0F; // 1.5 píxeles/segundo (mitad de velocidad)
top_clouds_sprite_a_->setSpriteClip(0, 0, top_clouds_texture_->getWidth(), top_clouds_texture_->getHeight());
top_clouds_sprite_a_->setVelX(-TOP_CLOUDS_SPEED);
top_clouds_sprite_a_->setVelX(-INITIAL_TOP_CLOUDS_SPEED_PX_PER_S);
top_clouds_sprite_b_->setSpriteClip(0, 0, top_clouds_texture_->getWidth(), top_clouds_texture_->getHeight());
top_clouds_sprite_b_->setVelX(-TOP_CLOUDS_SPEED);
top_clouds_sprite_b_->setVelX(-INITIAL_TOP_CLOUDS_SPEED_PX_PER_S);
bottom_clouds_sprite_a_->setSpriteClip(0, 0, bottom_clouds_texture_->getWidth(), bottom_clouds_texture_->getHeight());
bottom_clouds_sprite_a_->setVelX(-BOTTOM_CLOUDS_SPEED);
bottom_clouds_sprite_a_->setVelX(-INITIAL_BOTTOM_CLOUDS_SPEED_PX_PER_S);
bottom_clouds_sprite_b_->setSpriteClip(0, 0, bottom_clouds_texture_->getWidth(), bottom_clouds_texture_->getHeight());
bottom_clouds_sprite_b_->setVelX(-BOTTOM_CLOUDS_SPEED);
bottom_clouds_sprite_b_->setVelX(-INITIAL_BOTTOM_CLOUDS_SPEED_PX_PER_S);
buildings_sprite_->setY(base_ - buildings_sprite_->getHeight());
grass_sprite_->setY(base_ - grass_sprite_->getHeight());
@@ -129,7 +132,7 @@ void Background::initializeTextures() {
void Background::update(float delta_time) {
// Actualiza la progresión y calcula transiciones
if (!manual_mode_) {
updateProgression();
updateProgression(delta_time);
}
// Actualiza el valor de alpha
@@ -183,6 +186,12 @@ void Background::setProgress(float absolute_progress) {
// Cambia el estado del fondo
void Background::setState(State new_state) {
// Si entra en estado completado, inicializar variables de transición
if (new_state == State::COMPLETED && state_ != State::COMPLETED) {
completion_initial_progress_ = progress_;
completion_transition_timer_ = 0.0f;
}
state_ = new_state;
}
@@ -197,6 +206,10 @@ void Background::reset() {
sun_index_ = 0;
moon_index_ = 0;
// Resetear variables de transición de completado
completion_transition_timer_ = 0.0f;
completion_initial_progress_ = 0.0f;
// Notifica el cambio si hay callback
if (progress_callback_ && progress_ != old_progress) {
progress_callback_(progress_);
@@ -253,13 +266,24 @@ void Background::setMoonProgression(float progress) {
}
// Actualiza la progresión y calcula las transiciones
void Background::updateProgression() {
// Si el juego está completado, reduce la progresión gradualmente
void Background::updateProgression(float delta_time) {
// Si el juego está completado, hacer transición suave con easing
if (state_ == State::COMPLETED) {
if (progress_ > MINIMUM_COMPLETED_PROGRESS) {
progress_ -= COMPLETED_REDUCTION_RATE;
completion_transition_timer_ += delta_time;
// Calcular progreso normalizado de la transición (0.0 a 1.0)
float t = std::min(completion_transition_timer_ / COMPLETION_TRANSITION_DURATION_S, 1.0f);
if (t < 1.0f) {
// Usar easeOutCubic para transición suave (rápido al inicio, lento al final)
float eased_t = easeOutCubic(static_cast<double>(t));
// Interpolación desde progreso inicial hasta mínimo
float progress_range = completion_initial_progress_ - minimum_completed_progress_;
progress_ = completion_initial_progress_ - (progress_range * eased_t);
} else {
progress_ = MINIMUM_COMPLETED_PROGRESS;
// Transición completada, fijar al valor mínimo
progress_ = minimum_completed_progress_;
}
}
@@ -284,18 +308,19 @@ void Background::updateProgression() {
// Actualiza la velocidad de las nubes según el estado y progresión
void Background::updateCloudsSpeed() {
// Cálculo de velocidad según progreso
constexpr float CLOUDS_INITIAL_SPEED = 0.05F;
constexpr float CLOUDS_FINAL_SPEED = 2.00F - CLOUDS_INITIAL_SPEED;
// Cálculo de velocidad según progreso (convertido de frame-based a time-based)
constexpr float CLOUDS_INITIAL_SPEED_PX_PER_S = 0.05F * 60.0F; // 3.0 píxeles/segundo (era 0.05 px/frame @ 60fps)
constexpr float CLOUDS_TOTAL_SPEED_PX_PER_S = 2.00F * 60.0F; // 120.0 píxeles/segundo (era 2.00 px/frame @ 60fps)
constexpr float CLOUDS_FINAL_SPEED_RANGE_PX_PER_S = CLOUDS_TOTAL_SPEED_PX_PER_S - CLOUDS_INITIAL_SPEED_PX_PER_S; // 117.0 píxeles/segundo
// Velocidad base según progreso (de -0.05 a -2.00)
float base_clouds_speed = (-CLOUDS_INITIAL_SPEED) +
(-CLOUDS_FINAL_SPEED * (progress_ / total_progress_to_complete_));
// Velocidad base según progreso (de -3.0 a -120.0 píxeles/segundo, igual que la versión original)
float base_clouds_speed = (-CLOUDS_INITIAL_SPEED_PX_PER_S) +
(-CLOUDS_FINAL_SPEED_RANGE_PX_PER_S * (progress_ / total_progress_to_complete_));
// En estado completado, las nubes se ralentizan gradualmente
if (state_ == State::COMPLETED) {
float completion_factor = (progress_ - MINIMUM_COMPLETED_PROGRESS) /
(total_progress_to_complete_ - MINIMUM_COMPLETED_PROGRESS);
float completion_factor = (progress_ - minimum_completed_progress_) /
(total_progress_to_complete_ - minimum_completed_progress_);
completion_factor = std::max(0.1F, completion_factor);
base_clouds_speed *= completion_factor;
}

View File

@@ -27,7 +27,7 @@ class Background {
using ProgressCallback = std::function<void(float)>; // Callback para sincronización
// --- Constructor y destructor ---
Background(float total_progress_to_complete = 6100.0F); // Constructor principal
Background(float total_progress_to_complete); // Constructor principal
~Background(); // Destructor
// --- Métodos principales ---
@@ -61,9 +61,9 @@ class Background {
private:
// --- Constantes ---
static constexpr size_t STAGES = 4; // Número de etapas
static constexpr float COMPLETED_REDUCTION_RATE = 25.0F; // Tasa de reducción completada
static constexpr float MINIMUM_COMPLETED_PROGRESS = 200.0F; // Progreso mínimo completado
static constexpr float MINIMUM_COMPLETED_PROGRESS_PERCENTAGE = 0.05F; // Porcentaje mínimo completado (10%)
static constexpr float SUN_COMPLETION_FACTOR = 0.5F; // Factor de completado del sol
static constexpr float COMPLETION_TRANSITION_DURATION_S = 3.0F; // Duración de la transición de completado en segundos
// --- Objetos y punteros ---
SDL_Renderer *renderer_; // Renderizador de la ventana
@@ -90,6 +90,7 @@ class Background {
const float total_progress_to_complete_; // Progreso total para completar
const float progress_per_stage_; // Progreso por etapa
const float sun_completion_progress_; // Progreso de completado del sol
const float minimum_completed_progress_; // Progreso mínimo calculado dinámicamente
ProgressCallback progress_callback_; // Callback para notificar cambios de progreso
// --- Variables de estado ---
@@ -117,13 +118,17 @@ class Background {
Uint8 alpha_ = 0; // Transparencia entre fases
bool manual_mode_ = false; // Si está en modo manual
// --- Variables para transición suave de completado ---
float completion_transition_timer_ = 0.0f; // Timer para la transición de completado
float completion_initial_progress_ = 0.0f; // Progreso inicial al entrar en estado completado
// --- Métodos internos ---
void initializePaths(); // Inicializa las rutas del sol y la luna
void initializeRects(); // Inicializa los rectángulos de gradientes y nubes
void initializeSprites(); // Crea los sprites
void initializeSpriteProperties(); // Configura las propiedades iniciales de los sprites
void initializeTextures(); // Inicializa las texturas de renderizado
void updateProgression(); // Actualiza la progresión y calcula transiciones
void updateProgression(float delta_time); // Actualiza la progresión y calcula transiciones
void updateCloudsSpeed(); // Actualiza la velocidad de las nubes según el estado
void renderGradient(); // Dibuja el gradiente de fondo
void renderTopClouds(); // Dibuja las nubes superiores