arreglat bug en el estat pre del fade

This commit is contained in:
2025-08-17 20:17:55 +02:00
parent 3fc15a9512
commit 5e5227305f
4 changed files with 190 additions and 3 deletions

View File

@@ -56,6 +56,11 @@ void Fade::reset() {
// Pinta una transición en pantalla // Pinta una transición en pantalla
void Fade::render() { void Fade::render() {
if (state_ != State::NOT_ENABLED) { if (state_ != State::NOT_ENABLED) {
// Para fade IN terminado, no renderizar (auto-desactivación visual)
if (state_ == State::FINISHED && mode_ == Mode::IN) {
return;
}
SDL_RenderTexture(renderer_, backbuffer_, nullptr, nullptr); SDL_RenderTexture(renderer_, backbuffer_, nullptr, nullptr);
} }
} }
@@ -83,6 +88,10 @@ void Fade::updatePreState() {
if (elapsed_time >= static_cast<Uint32>(pre_duration_)) { if (elapsed_time >= static_cast<Uint32>(pre_duration_)) {
state_ = State::FADING; state_ = State::FADING;
// CRÍTICO: Reinicializar tiempo de inicio para tipos que usan random_squares_start_time_
if (type_ == Type::RANDOM_SQUARE2 || type_ == Type::DIAGONAL) {
random_squares_start_time_ = SDL_GetTicks();
}
} }
} }
@@ -100,6 +109,9 @@ void Fade::updateFadingState() {
case Type::RANDOM_SQUARE2: case Type::RANDOM_SQUARE2:
updateRandomSquare2Fade(); updateRandomSquare2Fade();
break; break;
case Type::DIAGONAL:
updateDiagonalFade();
break;
case Type::VENETIAN: case Type::VENETIAN:
updateVenetianFade(); updateVenetianFade();
break; break;
@@ -124,7 +136,7 @@ void Fade::updatePostState() {
// Mantener el alpha final correcto para cada tipo de fade // Mantener el alpha final correcto para cada tipo de fade
Uint8 post_alpha = a_; Uint8 post_alpha = a_;
if (type_ == Type::RANDOM_SQUARE2) { if (type_ == Type::RANDOM_SQUARE2 || type_ == Type::DIAGONAL) {
post_alpha = (mode_ == Mode::OUT) ? 255 : 0; post_alpha = (mode_ == Mode::OUT) ? 255 : 0;
} }
@@ -263,6 +275,150 @@ void Fade::updateRandomSquare2Fade() {
} }
} }
void Fade::updateDiagonalFade() {
Uint32 elapsed_time = SDL_GetTicks() - random_squares_start_time_;
int total_squares = num_squares_width_ * num_squares_height_;
// Calcula el tiempo de activación: total - tiempo que necesitan los últimos cuadrados
int activation_time = random_squares_duration_ - square_transition_duration_;
activation_time = std::max(activation_time, square_transition_duration_);
// Calcula cuántas diagonales deberían estar activas
int max_diagonal = num_squares_width_ + num_squares_height_ - 1; // Número total de diagonales
int active_diagonals = 0;
if (mode_ == Mode::OUT) {
// OUT: Activa diagonales gradualmente desde esquina superior izquierda
if (elapsed_time < static_cast<Uint32>(activation_time)) {
float activation_progress = static_cast<float>(elapsed_time) / activation_time;
active_diagonals = static_cast<int>(activation_progress * max_diagonal);
} else {
active_diagonals = max_diagonal; // Activar todas
}
// Activa cuadrados por diagonales
for (int diagonal = 0; diagonal < active_diagonals; ++diagonal) {
activateDiagonal(diagonal, elapsed_time);
}
} else {
// IN: Todas las diagonales empiezan activas, van desapareciendo
active_diagonals = max_diagonal;
// Activa diagonales gradualmente para transición
if (elapsed_time < static_cast<Uint32>(activation_time)) {
float activation_progress = static_cast<float>(elapsed_time) / activation_time;
int diagonals_starting_transition = static_cast<int>(activation_progress * max_diagonal);
for (int diagonal = 0; diagonal < diagonals_starting_transition; ++diagonal) {
activateDiagonal(diagonal, elapsed_time);
}
} else {
// Activar transición en todas las diagonales restantes
for (int diagonal = 0; diagonal < max_diagonal; ++diagonal) {
activateDiagonal(diagonal, elapsed_time);
}
}
}
drawDiagonal();
value_ = calculateValue(0, total_squares, active_diagonals * (total_squares / max_diagonal));
// Comprueba si ha terminado - todas las diagonales activadas y último cuadrado completó transición
bool all_completed = (active_diagonals >= max_diagonal);
if (all_completed) {
// Verificar que todos han completado su transición individual
for (int i = 0; i < total_squares; ++i) {
if (square_age_[i] >= 0) { // Cuadrado activado
Uint32 square_elapsed = elapsed_time - square_age_[i];
if (square_elapsed < static_cast<Uint32>(square_transition_duration_)) {
all_completed = false;
break;
}
}
}
if (all_completed) {
// Pintar textura final: OUT opaca, IN transparente
Uint8 final_alpha = (mode_ == Mode::OUT) ? 255 : 0;
cleanBackbuffer(r_, g_, b_, final_alpha);
changeToPostState();
}
}
}
void Fade::activateDiagonal(int diagonal_index, Uint32 current_time) {
// Para cada diagonal, activamos los cuadrados que pertenecen a esa diagonal
// Diagonal 0: (0,0)
// Diagonal 1: (1,0), (0,1)
// Diagonal 2: (2,0), (1,1), (0,2)
// etc.
for (int x = 0; x < num_squares_width_; ++x) {
int y = diagonal_index - x;
// Verificar que y está dentro de los límites
if (y >= 0 && y < num_squares_height_) {
// Convertir coordenadas (x,y) a índice en el vector
int index = y * num_squares_width_ + x;
if (index >= 0 && index < static_cast<int>(square_age_.size())) {
if (square_age_[index] == -1) {
square_age_[index] = current_time; // Guarda el tiempo de activación
}
}
}
}
}
void Fade::drawDiagonal() {
auto *temp = SDL_GetRenderTarget(renderer_);
SDL_SetRenderTarget(renderer_, backbuffer_);
// CRÍTICO: Limpiar la textura antes de dibujar
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0);
SDL_RenderClear(renderer_);
SDL_BlendMode blend_mode;
SDL_GetRenderDrawBlendMode(renderer_, &blend_mode);
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND); // Usar BLEND para alpha
Uint32 current_time = SDL_GetTicks() - random_squares_start_time_;
// Lógica unificada: sobre textura transparente, pintar cuadrados según su estado
for (size_t i = 0; i < square_.size(); ++i) {
Uint8 current_alpha = 0;
if (square_age_[i] == -1) {
// Cuadrado no activado
if (mode_ == Mode::OUT) {
current_alpha = 0; // OUT: transparente si no activado
} else {
current_alpha = a_; // IN: opaco si no activado
}
} else {
// Cuadrado activado - calculamos progreso
Uint32 square_elapsed = current_time - square_age_[i];
float progress = std::min(static_cast<float>(square_elapsed) / square_transition_duration_, 1.0f);
if (mode_ == Mode::OUT) {
current_alpha = static_cast<Uint8>(progress * a_); // 0 → 255
} else {
current_alpha = static_cast<Uint8>((1.0f - progress) * a_); // 255 → 0
}
}
if (current_alpha > 0) {
SDL_SetRenderDrawColor(renderer_, r_, g_, b_, current_alpha);
SDL_RenderFillRect(renderer_, &square_[i]);
}
}
SDL_SetRenderDrawBlendMode(renderer_, blend_mode);
SDL_SetRenderTarget(renderer_, temp);
}
void Fade::drawRandomSquares(int active_count) { void Fade::drawRandomSquares(int active_count) {
auto *temp = SDL_GetRenderTarget(renderer_); auto *temp = SDL_GetRenderTarget(renderer_);
SDL_SetRenderTarget(renderer_, backbuffer_); SDL_SetRenderTarget(renderer_, backbuffer_);
@@ -471,6 +627,33 @@ void Fade::activate() {
break; break;
} }
case Type::DIAGONAL: {
rect1_ = {.x = 0, .y = 0, .w = static_cast<float>(param.game.width / num_squares_width_), .h = static_cast<float>(param.game.height / num_squares_height_)};
square_.clear();
square_age_.clear();
// Añade los cuadrados al vector en orden (sin desordenar)
for (int i = 0; i < num_squares_width_ * num_squares_height_; ++i) {
rect1_.x = (i % num_squares_width_) * rect1_.w;
rect1_.y = (i / num_squares_width_) * rect1_.h;
square_.push_back(rect1_);
square_age_.push_back(-1); // -1 indica cuadrado no activado aún
}
// Textura inicial: OUT transparente, IN opaca
Uint8 initial_alpha = (mode_ == Mode::OUT) ? 0 : 255;
cleanBackbuffer(r_, g_, b_, initial_alpha);
// Deja el color listo para usar (alpha target para los cuadrados)
a_ = 255; // Siempre usar 255 como alpha target
// Inicializa el tiempo de inicio y recalcula la duración de transición
random_squares_start_time_ = SDL_GetTicks();
square_transition_duration_ = std::max(random_squares_duration_ / 4, 100); // Mínimo 100ms
break;
}
case Type::VENETIAN: { case Type::VENETIAN: {
// Limpia la textura // Limpia la textura
a_ = mode_ == Mode::OUT ? 0 : 255; a_ = mode_ == Mode::OUT ? 0 : 255;

View File

@@ -15,7 +15,8 @@ class Fade {
CENTER = 1, // Fundido desde el centro CENTER = 1, // Fundido desde el centro
RANDOM_SQUARE = 2, // Fundido con cuadrados aleatorios RANDOM_SQUARE = 2, // Fundido con cuadrados aleatorios
RANDOM_SQUARE2 = 3, // Fundido con cuadrados aleatorios (variante 2) RANDOM_SQUARE2 = 3, // Fundido con cuadrados aleatorios (variante 2)
VENETIAN = 4, // Fundido tipo persiana veneciana DIAGONAL = 4, // Fundido diagonal desde esquina superior izquierda
VENETIAN = 5, // Fundido tipo persiana veneciana
}; };
enum class Mode : Uint8 { enum class Mode : Uint8 {
@@ -97,6 +98,7 @@ class Fade {
void updateCenterFade(); // Actualiza el fundido desde el centro void updateCenterFade(); // Actualiza el fundido desde el centro
void updateRandomSquareFade(); // Actualiza el fundido con cuadrados aleatorios void updateRandomSquareFade(); // Actualiza el fundido con cuadrados aleatorios
void updateRandomSquare2Fade(); // Actualiza el fundido con cuadrados aleatorios (variante 2) void updateRandomSquare2Fade(); // Actualiza el fundido con cuadrados aleatorios (variante 2)
void updateDiagonalFade(); // Actualiza el fundido diagonal
void updateVenetianFade(); // Actualiza el fundido tipo persiana veneciana void updateVenetianFade(); // Actualiza el fundido tipo persiana veneciana
void updateVenetianRectangles(); // Actualiza los rectángulos del efecto veneciano void updateVenetianRectangles(); // Actualiza los rectángulos del efecto veneciano
void calculateVenetianProgress(); // Calcula el progreso del efecto veneciano void calculateVenetianProgress(); // Calcula el progreso del efecto veneciano
@@ -105,5 +107,7 @@ class Fade {
void drawCenterFadeRectangles(); // Dibuja los rectángulos del fundido central void drawCenterFadeRectangles(); // Dibuja los rectángulos del fundido central
void drawRandomSquares(int active_count = -1); // Dibuja los cuadrados aleatorios del fundido void drawRandomSquares(int active_count = -1); // Dibuja los cuadrados aleatorios del fundido
void drawRandomSquares2(); // Dibuja los cuadrados con transición de color (RANDOM_SQUARE2) void drawRandomSquares2(); // Dibuja los cuadrados con transición de color (RANDOM_SQUARE2)
void drawDiagonal(); // Dibuja los cuadrados con patrón diagonal
void activateDiagonal(int diagonal_index, Uint32 current_time); // Activa una diagonal específica
void drawVenetianBlinds(); // Dibuja las persianas venecianas del fundido void drawVenetianBlinds(); // Dibuja las persianas venecianas del fundido
}; };

View File

@@ -1653,6 +1653,7 @@ void Game::updateDemo() {
// Activa el fundido antes de acabar con los datos de la demo // Activa el fundido antes de acabar con los datos de la demo
if (demo_.counter == TOTAL_DEMO_DATA - 200) { if (demo_.counter == TOTAL_DEMO_DATA - 200) {
fade_out_->setType(Fade::Type::RANDOM_SQUARE2); fade_out_->setType(Fade::Type::RANDOM_SQUARE2);
fade_out_->setPostDuration(param.fade.post_duration_ms);
fade_out_->activate(); fade_out_->activate();
} }

View File

@@ -259,7 +259,6 @@ class Game {
// --- Gestión de fases y progresión --- // --- Gestión de fases y progresión ---
void updateStage(); // Verifica y actualiza cambio de fase void updateStage(); // Verifica y actualiza cambio de fase
void setTotalPower(); // Calcula poder total necesario para completar el juego
void initDifficultyVars(); // Inicializa variables de dificultad void initDifficultyVars(); // Inicializa variables de dificultad
// --- Sistema de amenaza --- // --- Sistema de amenaza ---