#pragma once #include // for SDL_Renderer #include // 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() = default; // 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 y sprites (x2 - logo1 y logo2 superpuestos) std::shared_ptr logo1_texture_; // Textura del logo1 (data/logo/logo.png) std::unique_ptr logo1_sprite_; // Sprite para renderizar logo1 std::shared_ptr logo2_texture_; // Textura del logo2 (data/logo/logo2.png) std::unique_ptr logo2_sprite_; // Sprite para renderizar logo2 // 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 int current_alpha_ = 0; // Alpha actual (0-255) // Animaciones INDEPENDIENTES para cada logo AppLogoAnimationType logo1_entry_animation_ = AppLogoAnimationType::ZOOM_ONLY; AppLogoAnimationType logo1_exit_animation_ = AppLogoAnimationType::ZOOM_ONLY; AppLogoAnimationType logo2_entry_animation_ = AppLogoAnimationType::ZOOM_ONLY; AppLogoAnimationType logo2_exit_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(); };