// title.hpp - Animacions de naves i layout de l'escena de títol // © 2026 JailDesigner #pragma once #include #include #include "core/defaults/game.hpp" #include "core/defaults/math.hpp" #include "core/rendering/line_renderer.hpp" // Title scene ship animations (naves 3D flotantes a l'escena de título) namespace Defaults::Title { namespace Ships { // ============================================================ // PARÀMETRES BASE (ajustar aquí per experimentar) // ============================================================ // 1. Escala global de las naves constexpr float SHIP_BASE_SCALE = 2.5F; // Multiplicador (1.0 = mida original del .shp) // 2. Altura vertical (cercanía al centro) // Ratio Y desde el centro de la pantalla (0.0 = centro, 1.0 = bottom de pantalla) constexpr float TARGET_Y_RATIO = 0.15625F; // 3. Radio orbital (distance radial desde centro en coordenadas polares) constexpr float CLOCK_RADIUS = 150.0F; // Distancia des del centro // 4. Ángulos de posición (clock positions en coordenadas polares) // En coordenadas de pantalla: 0° = derecha, 90° = baix, 180° = izquierda, 270° = dalt constexpr float CLOCK_8_ANGLE = 150.0F * Math::PI / 180.0F; // 8 o'clock (bottom-left) constexpr float CLOCK_4_ANGLE = 30.0F * Math::PI / 180.0F; // 4 o'clock (bottom-right) // 5. Radio máximo de la shape de la nave (para calcular offset automáticamente) constexpr float SHIP_MAX_RADIUS = 30.0F; // Radi del cercle circumscrit a ship_starfield.shp // 6. Margen de seguridad para offset de entrada constexpr float ENTRY_OFFSET_MARGIN = 227.5F; // Para offset total de ~340px (ajustado) // ============================================================ // VALORS DERIVATS (calculats automáticoament - NO modificar) // ============================================================ // Centro de la pantalla (point de referència) constexpr float CENTER_X = Game::WIDTH / 2.0F; // auto-derivado de Game::WIDTH constexpr float CENTER_Y = Game::HEIGHT / 2.0F; // auto-derivado de Game::HEIGHT // Posicions target (calculades dinàmicament des dels parámetros base) // Nota: std::cos/sin no són constexpr en C++20, pero funcionen en runtime // Les funciones inline són optimitzades por el compilador (zero overhead) inline auto p1TargetX() -> float { return CENTER_X + (CLOCK_RADIUS * std::cos(CLOCK_8_ANGLE)); } inline auto p1TargetY() -> float { return CENTER_Y + ((Game::HEIGHT / 2.0F) * TARGET_Y_RATIO); } inline auto p2TargetX() -> float { return CENTER_X + (CLOCK_RADIUS * std::cos(CLOCK_4_ANGLE)); } inline auto p2TargetY() -> float { return CENTER_Y + ((Game::HEIGHT / 2.0F) * TARGET_Y_RATIO); } // Escales de animación (relatives a SHIP_BASE_SCALE) constexpr float ENTRY_SCALE_START = 1.5F * SHIP_BASE_SCALE; // Entrada: 50% més grande constexpr float FLOATING_SCALE = 1.0F * SHIP_BASE_SCALE; // Flotante: scale base // Offset de entrada (ajustat automáticoament a l'scale) // Fórmula: (radius màxim de la ship * scale de entrada) + margen constexpr float ENTRY_OFFSET = (SHIP_MAX_RADIUS * ENTRY_SCALE_START) + ENTRY_OFFSET_MARGIN; // Vec2 de fuga (centro para l'animación de salida) constexpr float VANISHING_POINT_X = CENTER_X; // auto-derivado de Game::WIDTH constexpr float VANISHING_POINT_Y = CENTER_Y; // auto-derivado de Game::HEIGHT // ============================================================ // ANIMACIONS (durades, oscil·lacions, delays) // ============================================================ // Durades de animación constexpr float ENTRY_DURATION = 2.0F; // Entrada (segons) constexpr float EXIT_DURATION = 1.5F; // Salida (segons) // Flotació (oscil·lació reduïda y diferenciada per ship) constexpr float FLOAT_AMPLITUDE_X = 4.0F; // Amplitud X (píxels) constexpr float FLOAT_AMPLITUDE_Y = 2.5F; // Amplitud Y (píxels) // Freqüències base constexpr float FLOAT_FREQUENCY_X_BASE = 0.5F; // Hz constexpr float FLOAT_FREQUENCY_Y_BASE = 0.7F; // Hz constexpr float FLOAT_PHASE_OFFSET = 1.57F; // π/2 (90°) // Delays de entrada (per a entrada escalonada) constexpr float P1_ENTRY_DELAY = 0.0F; // P1 entra immediatament constexpr float P2_ENTRY_DELAY = 0.5F; // P2 entra 0.5s después // Multiplicadors de freqüència para cada ship (variació sutil ±12%) constexpr float P1_FREQUENCY_MULTIPLIER = 0.88F; // 12% més lenta constexpr float P2_FREQUENCY_MULTIPLIER = 1.12F; // 12% més ràpida } // namespace Ships namespace Layout { // Posicions verticals (anclatges des del TOP de pantalla lógica, 0.0-1.0) constexpr float LOGO_POS = 0.20F; // Logo "ORNI" constexpr float PRESS_START_POS = 0.75F; // "PRESS START TO PLAY" constexpr float COPYRIGHT1_POS = 0.90F; // Primera línia copyright // Separacions relatives (proporció respecte Game::HEIGHT = 480px) constexpr float LOGO_LINE_SPACING = 0.02F; // Entre "ORNI" i "ATTACK!" (10px) constexpr float COPYRIGHT_LINE_SPACING = 0.0F; // Entre línies copyright (5px) // Factors de scale constexpr float LOGO_SCALE = 0.6F; // Escala "ORNI ATTACK!" constexpr float PRESS_START_SCALE = 1.0F; // Escala "PRESS START TO PLAY" constexpr float COPYRIGHT_SCALE = 0.5F; // Escala copyright constexpr float COPYRIGHT_BRIGHTNESS = 0.55F; // Mateix verd que JAILGAMES, però menys brillant constexpr float JAILGAMES_SCALE = 0.25F; // Escala del logo JAILGAMES pequeño sobre el copyright // Separación entre el logo JAILGAMES y la línea de copyright (proporción de Game::HEIGHT). constexpr float JAILGAMES_COPYRIGHT_GAP = 0.015F; // Espaiat entre caràcters (usado per VectorText) constexpr float TEXT_SPACING = 2.0F; } // namespace Layout // Coreografia de la seqüència d'entrada al state MAIN. // Tots els elements (logo, footer, naus, press start) entren ordenadament // segons aquests thresholds. Vegeu title_scene.cpp/updateMainState. // // Per al logo i el footer, l'efecte simula un moviment 3D des de l'usuari // cap al VP: el text arrenca gran i a la posició projectada extrema (com // si estigués prop de la càmera, fora de pantalla) i acaba a la seva // posició final amb escala normal (com si hagués aterrat al VP). Pivot: // centre de pantalla (= projecció del VP 3D). namespace Sequence { // Factor d'escala inicial. >1 = sprite gran a l'inici (prop de l'usuari). // La posició inicial es deriva: pivot=centre, delta multiplicat per aquest factor. constexpr float LOGO_INTRO_SCALE_START = 2.5F; constexpr float FOOTER_INTRO_SCALE_START = 2.5F; // Durades de les animacions d'entrada (segons). constexpr float LOGO_ENTRY_DURATION = 1.2F; constexpr float JAILGAMES_ENTRY_DURATION = 0.7F; constexpr float COPYRIGHT_ENTRY_DURATION = 0.7F; // Stagger "pam-pam" entre l'arrencada de JAILGAMES i la de COPYRIGHT. constexpr float COPYRIGHT_STAGGER = 0.18F; // Delays entre etapes. constexpr float SHIPS_DELAY_AFTER_FOOTER = 0.20F; constexpr float PRESS_START_DELAY_AFTER_SHIPS = 0.40F; } // namespace Sequence // Paleta neon de l'escena de títol (cian + magenta synthwave). // alpha = 255 (sentinela "color vàlid") fa que el pipeline ignori // el color global de l'oscil·lador per a aquesta crida. namespace Colors { constexpr SDL_Color LOGO_MAIN = {.r = 80, .g = 240, .b = 255, .a = 255}; // Cian elèctric constexpr SDL_Color LOGO_SHADOW = {.r = 255, .g = 60, .b = 180, .a = 255}; // Magenta neon (offset) constexpr SDL_Color SHIP_P1 = {.r = 255, .g = 100, .b = 200, .a = 255}; // Rosa hot constexpr SDL_Color SHIP_P2 = {.r = 160, .g = 120, .b = 255, .a = 255}; // Violeta elèctric constexpr SDL_Color STARFIELD = {.r = 200, .g = 220, .b = 255, .a = 255}; // Blanc-blau gel constexpr SDL_Color PRESS_START = {.r = 255, .g = 255, .b = 255, .a = 255}; // Blanc constexpr SDL_Color JAILGAMES_LOGO = ::Rendering::DEFAULT_LINE_COLOR; // Verd estàndard del joc constexpr SDL_Color COPYRIGHT = ::Rendering::DEFAULT_LINE_COLOR; // Mateix verd (el brillo es baixa al render: COPYRIGHT_BRIGHTNESS) } // namespace Colors } // namespace Defaults::Title