Implementa sistema de sincronización elegante entre logos con efecto de "seguimiento" y fade suavizado para eliminar desincronización visual. Cambios principales: 1. **Animación sincronizada**: Ambos logos usan la MISMA animación - Eliminadas 4 variables independientes (logo1/logo2 × entry/exit) - Una sola variable `current_animation_` compartida - Misma animación para entrada y salida (simetría) 2. **Retraso de Logo 2**: 0.25 segundos detrás de Logo 1 - Logo 1 empieza en t=0.00s - Logo 2 empieza en t=0.25s - Efecto visual de "eco" o "seguimiento" 3. **Alpha independiente con retraso**: - `logo1_alpha_` y `logo2_alpha_` separados - Logo 2 aparece/desaparece más tarde visualmente 4. **Easing en alpha** (NUEVO): - Aplicado `easeInOutQuad()` al fade de alpha - Elimina problema de "logo deformado esperando a desvanecerse" - Sincronización visual perfecta entre animación y fade - Curva suave: lento al inicio, rápido en medio, lento al final Comportamiento resultante: FADE_IN: - t=0.00s: Logo 1 empieza (alpha con easing) - t=0.25s: Logo 2 empieza (alpha con easing + retraso) - t=0.50s: Logo 1 completamente visible - t=0.75s: Logo 2 completamente visible FADE_OUT: - t=0.00s: Logo 1 empieza a desaparecer (misma animación) - t=0.25s: Logo 2 empieza a desaparecer - t=0.50s: Logo 1 completamente invisible - t=0.75s: Logo 2 completamente invisible Archivos modificados: - source/defines.h: +APPLOGO_LOGO2_DELAY - source/app_logo.h: Reestructuración de variables de animación/alpha - source/app_logo.cpp: Implementación de retraso + easing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
118 lines
5.4 KiB
C++
118 lines
5.4 KiB
C++
#pragma once
|
||
|
||
#include <SDL3/SDL_render.h> // for SDL_Renderer
|
||
|
||
#include <memory> // for unique_ptr, shared_ptr
|
||
|
||
#include "defines.h" // for AppMode
|
||
|
||
class Texture;
|
||
class Sprite;
|
||
|
||
// Estados de la máquina de estados del logo
|
||
enum class AppLogoState {
|
||
HIDDEN, // Logo oculto, esperando APPLOGO_DISPLAY_INTERVAL
|
||
FADE_IN, // Apareciendo (alpha 0 → 255)
|
||
VISIBLE, // Completamente visible, esperando APPLOGO_DISPLAY_DURATION
|
||
FADE_OUT // Desapareciendo (alpha 255 → 0)
|
||
};
|
||
|
||
// Tipo de animación de entrada/salida
|
||
enum class AppLogoAnimationType {
|
||
ZOOM_ONLY, // A: Solo zoom simple (120% → 100% → 120%)
|
||
ELASTIC_STICK, // B: Zoom + deformación elástica tipo "pegatina"
|
||
ROTATE_SPIRAL, // C: Rotación en espiral (entra girando, sale girando)
|
||
BOUNCE_SQUASH // D: Rebote con aplastamiento (cae rebotando, salta)
|
||
};
|
||
|
||
class AppLogo {
|
||
public:
|
||
AppLogo() = default;
|
||
~AppLogo(); // Necesario para liberar las 4 texturas SDL
|
||
|
||
// Inicializar textura y sprite del logo
|
||
bool initialize(SDL_Renderer* renderer, int screen_width, int screen_height);
|
||
|
||
// Actualizar temporizadores y estado de visibilidad
|
||
void update(float delta_time, AppMode current_mode);
|
||
|
||
// Renderizar logo si está visible
|
||
void render();
|
||
|
||
// Actualizar tamaño de pantalla (reposicionar logo)
|
||
void updateScreenSize(int screen_width, int screen_height);
|
||
|
||
private:
|
||
// ====================================================================
|
||
// Texturas pre-escaladas (4 texturas: 2 logos × 2 resoluciones)
|
||
// ====================================================================
|
||
SDL_Texture* logo1_base_texture_ = nullptr; // Logo1 para resolución base
|
||
SDL_Texture* logo1_native_texture_ = nullptr; // Logo1 para resolución nativa (F4)
|
||
SDL_Texture* logo2_base_texture_ = nullptr; // Logo2 para resolución base
|
||
SDL_Texture* logo2_native_texture_ = nullptr; // Logo2 para resolución nativa (F4)
|
||
|
||
// Dimensiones pre-calculadas para cada textura
|
||
int logo1_base_width_ = 0, logo1_base_height_ = 0;
|
||
int logo1_native_width_ = 0, logo1_native_height_ = 0;
|
||
int logo2_base_width_ = 0, logo2_base_height_ = 0;
|
||
int logo2_native_width_ = 0, logo2_native_height_ = 0;
|
||
|
||
// Texturas actualmente en uso (apuntan a base o native según resolución)
|
||
SDL_Texture* logo1_current_texture_ = nullptr;
|
||
SDL_Texture* logo2_current_texture_ = nullptr;
|
||
int logo1_current_width_ = 0, logo1_current_height_ = 0;
|
||
int logo2_current_width_ = 0, logo2_current_height_ = 0;
|
||
|
||
// Resoluciones conocidas
|
||
int base_screen_width_ = 0, base_screen_height_ = 0; // Resolución inicial
|
||
int native_screen_width_ = 0, native_screen_height_ = 0; // Resolución nativa (F4)
|
||
|
||
// ====================================================================
|
||
// Variables COMPARTIDAS (sincronización de ambos logos)
|
||
// ====================================================================
|
||
AppLogoState state_ = AppLogoState::HIDDEN; // Estado actual de la máquina de estados
|
||
float timer_ = 0.0f; // Contador de tiempo para estado actual
|
||
|
||
// Alpha INDEPENDIENTE para cada logo (Logo 2 con retraso)
|
||
int logo1_alpha_ = 0; // Alpha de Logo 1 (0-255)
|
||
int logo2_alpha_ = 0; // Alpha de Logo 2 (0-255, con retraso)
|
||
|
||
// Animación COMPARTIDA (misma para ambos logos, misma entrada y salida)
|
||
AppLogoAnimationType current_animation_ = AppLogoAnimationType::ZOOM_ONLY;
|
||
|
||
// Variables de deformación INDEPENDIENTES para logo1
|
||
float logo1_scale_ = 1.0f; // Escala actual de logo1 (1.0 = 100%)
|
||
float logo1_squash_y_ = 1.0f; // Factor de aplastamiento vertical logo1
|
||
float logo1_stretch_x_ = 1.0f; // Factor de estiramiento horizontal logo1
|
||
float logo1_rotation_ = 0.0f; // Rotación en radianes logo1
|
||
|
||
// Variables de deformación INDEPENDIENTES para logo2
|
||
float logo2_scale_ = 1.0f; // Escala actual de logo2 (1.0 = 100%)
|
||
float logo2_squash_y_ = 1.0f; // Factor de aplastamiento vertical logo2
|
||
float logo2_stretch_x_ = 1.0f; // Factor de estiramiento horizontal logo2
|
||
float logo2_rotation_ = 0.0f; // Rotación en radianes logo2
|
||
|
||
int screen_width_ = 0; // Ancho de pantalla (para centrar)
|
||
int screen_height_ = 0; // Alto de pantalla (para centrar)
|
||
|
||
// Tamaño base del logo (calculado una vez)
|
||
float base_width_ = 0.0f;
|
||
float base_height_ = 0.0f;
|
||
|
||
// SDL renderer (necesario para renderizado con geometría)
|
||
SDL_Renderer* renderer_ = nullptr;
|
||
|
||
// Métodos privados auxiliares
|
||
void updateLogoPosition(); // Centrar ambos logos en pantalla (superpuestos)
|
||
void renderWithGeometry(int logo_index); // Renderizar logo con vértices deformados (1 o 2)
|
||
|
||
// Funciones de easing
|
||
float easeOutElastic(float t); // Elastic bounce out
|
||
float easeOutBack(float t); // Overshoot out
|
||
float easeOutBounce(float t); // Bounce easing (para BOUNCE_SQUASH)
|
||
float easeInOutQuad(float t); // Quadratic easing (para ROTATE_SPIRAL)
|
||
|
||
// Función auxiliar para elegir animación aleatoria
|
||
AppLogoAnimationType getRandomAnimation();
|
||
};
|