// init_hud_animator.cpp - Implementación de la animación inicial del HUD #include "game/systems/init_hud_animator.hpp" #include #include #include #include "core/defaults.hpp" #include "core/math/easing.hpp" #include "core/rendering/line_renderer.hpp" namespace Systems::InitHud { auto computeRangeProgress(float global_progress, float ratio_init, float ratio_end) -> float { if (ratio_init >= ratio_end) { return (global_progress >= ratio_end) ? 1.0F : 0.0F; } if (global_progress < ratio_init) { return 0.0F; } if (global_progress > ratio_end) { return 1.0F; } return (global_progress - ratio_init) / (ratio_end - ratio_init); } auto computeShipPosition(float progress, const Vec2& final_position) -> Vec2 { const float EASED = Easing::easeOutQuad(progress); const SDL_FRect& zone = Defaults::Zones::PLAYAREA; // Y inicial: 50 px bajo la zona de juego. const float Y_INI = zone.y + zone.h + 50.0F; const float Y_ANIM = Y_INI + ((final_position.y - Y_INI) * EASED); return Vec2{.x = final_position.x, .y = Y_ANIM}; } void drawBordersAnimated(Rendering::Renderer* renderer, float progress) { const SDL_FRect& zone = Defaults::Zones::PLAYAREA; const float EASED = Easing::easeOutQuad(progress); const int X1 = static_cast(zone.x); const int Y1 = static_cast(zone.y); const int X2 = static_cast(zone.x + zone.w); const int Y2 = static_cast(zone.y + zone.h); const int CX = (X1 + X2) / 2; constexpr float PHASE_1_END = 0.33F; constexpr float PHASE_2_END = 0.66F; // Fase 1: línea superior crece desde el centro hacia los lados. if (EASED > 0.0F) { const float P = std::min(EASED / PHASE_1_END, 1.0F); const int X_LEFT = static_cast(CX - ((CX - X1) * P)); const int X_RIGHT = static_cast(CX + ((X2 - CX) * P)); Rendering::linea(renderer, CX, Y1, X_LEFT, Y1); Rendering::linea(renderer, CX, Y1, X_RIGHT, Y1); } // Fase 2: laterales bajan. if (EASED > PHASE_1_END) { const float P = std::min((EASED - PHASE_1_END) / (PHASE_2_END - PHASE_1_END), 1.0F); const int Y_BOTTOM = static_cast(Y1 + ((Y2 - Y1) * P)); Rendering::linea(renderer, X1, Y1, X1, Y_BOTTOM); Rendering::linea(renderer, X2, Y1, X2, Y_BOTTOM); } // Fase 3: línea inferior crece desde los lados hacia el centro. if (EASED > PHASE_2_END) { const float P = (EASED - PHASE_2_END) / (1.0F - PHASE_2_END); const int X_LEFT = static_cast(X1 + ((CX - X1) * P)); const int X_RIGHT = static_cast(X2 - ((X2 - CX) * P)); Rendering::linea(renderer, X1, Y2, X_LEFT, Y2); Rendering::linea(renderer, X2, Y2, X_RIGHT, Y2); } } void drawScoreboardAnimated(const Graphics::VectorText& text, const std::string& scoreboard_text, float progress) { const float EASED = Easing::easeOutQuad(progress); constexpr float SCALE = 0.85F; constexpr float SPACING = 0.0F; const SDL_FRect& scoreboard_zone = Defaults::Zones::SCOREBOARD; const float CENTRE_X = scoreboard_zone.w / 2.0F; const float Y_FINAL = scoreboard_zone.y + (scoreboard_zone.h / 2.0F); // Posición inicial: fuera de la pantalla por debajo. const auto Y_INI = static_cast(Defaults::Game::HEIGHT); const float Y_ANIM = Y_INI + ((Y_FINAL - Y_INI) * EASED); text.renderCentered(scoreboard_text, Vec2{.x = CENTRE_X, .y = Y_ANIM}, SCALE, SPACING); } } // namespace Systems::InitHud