Fase 9c: extraer InitHudAnimator de GameScene
GameScene::dibuixar_marges_animat, dibuixar_marcador_animat,
calcular_posicio_nau_init_hud y calcular_progress_rango (4 funciones,
~135 LOC) salen a Systems::InitHud en
source/game/systems/init_hud_animator.{hpp,cpp}.
Las funciones son puras (sin estado interno propio). API libre en
namespace:
- computeRangeProgress(global, init, end): normalizacion de la
ventana de progreso de un elemento dentro del global 0..1.
- computeShipPosition(progress, final_position): interpola Y desde
fuera de pantalla con ease_out_quad.
- drawBordersAnimated(renderer, progress): efecto pincel en 3 fases.
- drawScoreboardAnimated(text, scoreboard_text, progress): texto
subiendo desde abajo.
GameScene inyecta lo que cada funcion necesita por parametro
(spawn point desde obtenir_punt_spawn, scoreboard desde
buildScoreboard). Sin estado mutable compartido.
GameScene.cpp acumulado tras 9a/9b/9c: 1429 -> 1043 LOC.
Smoke test xvfb OK.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include "game/stage_system/stage_loader.hpp"
|
||||
#include "game/systems/collision_system.hpp"
|
||||
#include "game/systems/continue_system.hpp"
|
||||
#include "game/systems/init_hud_animator.hpp"
|
||||
|
||||
// Using declarations per simplificar el codi
|
||||
using SceneManager::SceneContext;
|
||||
@@ -429,24 +430,24 @@ void GameScene::update(float delta_time) {
|
||||
global_progress = std::min(1.0F, global_progress);
|
||||
|
||||
// [NEW] Calcular progress independiente para cada nave
|
||||
float ship1_progress = calcular_progress_rango(
|
||||
float ship1_progress = Systems::InitHud::computeRangeProgress(
|
||||
global_progress,
|
||||
Defaults::Game::INIT_HUD_SHIP1_RATIO_INIT,
|
||||
Defaults::Game::INIT_HUD_SHIP1_RATIO_END);
|
||||
|
||||
float ship2_progress = calcular_progress_rango(
|
||||
float ship2_progress = Systems::InitHud::computeRangeProgress(
|
||||
global_progress,
|
||||
Defaults::Game::INIT_HUD_SHIP2_RATIO_INIT,
|
||||
Defaults::Game::INIT_HUD_SHIP2_RATIO_END);
|
||||
|
||||
// [MODIFICAT] Animar AMBAS naves con sus progress respectivos
|
||||
if (match_config_.jugador1_actiu && ship1_progress < 1.0F) {
|
||||
Vec2 pos_p1 = calcular_posicio_nau_init_hud(ship1_progress, 0);
|
||||
Vec2 pos_p1 = Systems::InitHud::computeShipPosition(ship1_progress, obtenir_punt_spawn(0));
|
||||
ships_[0].setCenter(pos_p1);
|
||||
}
|
||||
|
||||
if (match_config_.jugador2_actiu && ship2_progress < 1.0F) {
|
||||
Vec2 pos_p2 = calcular_posicio_nau_init_hud(ship2_progress, 1);
|
||||
Vec2 pos_p2 = Systems::InitHud::computeShipPosition(ship2_progress, obtenir_punt_spawn(1));
|
||||
ships_[1].setCenter(pos_p2);
|
||||
}
|
||||
|
||||
@@ -630,22 +631,22 @@ void GameScene::draw() {
|
||||
float global_progress = 1.0F - (timer / total_time);
|
||||
|
||||
// [NEW] Calcular progress independiente para cada elemento
|
||||
float rect_progress = calcular_progress_rango(
|
||||
float rect_progress = Systems::InitHud::computeRangeProgress(
|
||||
global_progress,
|
||||
Defaults::Game::INIT_HUD_RECT_RATIO_INIT,
|
||||
Defaults::Game::INIT_HUD_RECT_RATIO_END);
|
||||
|
||||
float score_progress = calcular_progress_rango(
|
||||
float score_progress = Systems::InitHud::computeRangeProgress(
|
||||
global_progress,
|
||||
Defaults::Game::INIT_HUD_SCORE_RATIO_INIT,
|
||||
Defaults::Game::INIT_HUD_SCORE_RATIO_END);
|
||||
|
||||
float ship1_progress = calcular_progress_rango(
|
||||
float ship1_progress = Systems::InitHud::computeRangeProgress(
|
||||
global_progress,
|
||||
Defaults::Game::INIT_HUD_SHIP1_RATIO_INIT,
|
||||
Defaults::Game::INIT_HUD_SHIP1_RATIO_END);
|
||||
|
||||
float ship2_progress = calcular_progress_rango(
|
||||
float ship2_progress = Systems::InitHud::computeRangeProgress(
|
||||
global_progress,
|
||||
Defaults::Game::INIT_HUD_SHIP2_RATIO_INIT,
|
||||
Defaults::Game::INIT_HUD_SHIP2_RATIO_END);
|
||||
@@ -658,11 +659,11 @@ void GameScene::draw() {
|
||||
init_hud_rect_sound_played_ = true;
|
||||
}
|
||||
|
||||
dibuixar_marges_animat(rect_progress);
|
||||
Systems::InitHud::drawBordersAnimated(sdl_.getRenderer(), rect_progress);
|
||||
}
|
||||
|
||||
if (score_progress > 0.0F) {
|
||||
dibuixar_marcador_animat(score_progress);
|
||||
Systems::InitHud::drawScoreboardAnimated(text_, buildScoreboard(), score_progress);
|
||||
}
|
||||
|
||||
// [MODIFICAT] Dibuixar naves con progress independent
|
||||
@@ -824,142 +825,6 @@ void GameScene::dibuixar_marcador() {
|
||||
text_.renderCentered(text, {.x = centre_x, .y = centre_y}, scale, spacing);
|
||||
}
|
||||
|
||||
void GameScene::dibuixar_marges_animat(float progress) const {
|
||||
// Animación seqüencial del rectangle con efecte de "pinzell"
|
||||
// Dos pinzells comencen al centro superior i baixen por los laterals
|
||||
|
||||
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
|
||||
|
||||
// Aplicar easing al progrés global
|
||||
float eased_progress = Easing::ease_out_quad(progress);
|
||||
|
||||
// Coordenades del rectangle complet
|
||||
int x1 = static_cast<int>(zona.x);
|
||||
int y1 = static_cast<int>(zona.y);
|
||||
int x2 = static_cast<int>(zona.x + zona.w);
|
||||
int y2 = static_cast<int>(zona.y + zona.h);
|
||||
int cx = (x1 + x2) / 2;
|
||||
|
||||
// Dividir en 3 fases de 33% cada una
|
||||
constexpr float PHASE_1_END = 0.33F;
|
||||
constexpr float PHASE_2_END = 0.66F;
|
||||
|
||||
// --- FASE 1: Línies horitzontals superiors (0-33%) ---
|
||||
if (eased_progress > 0.0F) {
|
||||
float phase1_progress = std::min(eased_progress / PHASE_1_END, 1.0F);
|
||||
|
||||
// Línia izquierda: creix des del centro hacia l'izquierda
|
||||
int x1_phase1 = static_cast<int>(cx - ((cx - x1) * phase1_progress));
|
||||
Rendering::linea(sdl_.getRenderer(), cx, y1, x1_phase1, y1);
|
||||
|
||||
// Línia derecha: creix des del centro hacia la derecha
|
||||
int x2_phase1 = static_cast<int>(cx + ((x2 - cx) * phase1_progress));
|
||||
Rendering::linea(sdl_.getRenderer(), cx, y1, x2_phase1, y1);
|
||||
}
|
||||
|
||||
// --- FASE 2: Línies verticals laterals (33-66%) ---
|
||||
if (eased_progress > PHASE_1_END) {
|
||||
float phase2_progress = std::min((eased_progress - PHASE_1_END) / (PHASE_2_END - PHASE_1_END), 1.0F);
|
||||
|
||||
// Línia izquierda: creix desde dalt hacia baix
|
||||
int y2_phase2 = static_cast<int>(y1 + ((y2 - y1) * phase2_progress));
|
||||
Rendering::linea(sdl_.getRenderer(), x1, y1, x1, y2_phase2);
|
||||
|
||||
// Línia derecha: creix desde dalt hacia baix
|
||||
Rendering::linea(sdl_.getRenderer(), x2, y1, x2, y2_phase2);
|
||||
}
|
||||
|
||||
// --- FASE 3: Línies horitzontals inferiors (66-100%) ---
|
||||
if (eased_progress > PHASE_2_END) {
|
||||
float phase3_progress = (eased_progress - PHASE_2_END) / (1.0F - PHASE_2_END);
|
||||
|
||||
// Línia izquierda: creix desde l'izquierda hacia el centro
|
||||
int x_left_phase3 = static_cast<int>(x1 + ((cx - x1) * phase3_progress));
|
||||
Rendering::linea(sdl_.getRenderer(), x1, y2, x_left_phase3, y2);
|
||||
|
||||
// Línia derecha: creix desde la derecha hacia el centro
|
||||
int x_right_phase3 = static_cast<int>(x2 - ((x2 - cx) * phase3_progress));
|
||||
Rendering::linea(sdl_.getRenderer(), x2, y2, x_right_phase3, y2);
|
||||
}
|
||||
}
|
||||
|
||||
void GameScene::dibuixar_marcador_animat(float progress) {
|
||||
// Animación del marcador pujant desde baix con easing
|
||||
|
||||
// Calcular progrés con easing
|
||||
float eased_progress = Easing::ease_out_quad(progress);
|
||||
|
||||
// Construir text
|
||||
std::string text = buildScoreboard();
|
||||
|
||||
// Parámetros
|
||||
const float scale = 0.85F;
|
||||
const float spacing = 0.0F;
|
||||
|
||||
// Calcular centro de la zona del marcador
|
||||
const SDL_FRect& scoreboard = Defaults::Zones::SCOREBOARD;
|
||||
float centre_x = scoreboard.w / 2.0F;
|
||||
float centre_y_final = scoreboard.y + (scoreboard.h / 2.0F);
|
||||
|
||||
// Posición Y inicial (offscreen, sota de la pantalla)
|
||||
auto centre_y_inicial = static_cast<float>(Defaults::Game::HEIGHT);
|
||||
|
||||
// Interpolació con easing
|
||||
float centre_y_animada = centre_y_inicial + ((centre_y_final - centre_y_inicial) * eased_progress);
|
||||
|
||||
// Renderizar centrat en posición animada
|
||||
text_.renderCentered(text, {.x = centre_x, .y = centre_y_animada}, scale, spacing);
|
||||
}
|
||||
|
||||
Vec2 GameScene::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const {
|
||||
// Animación de la ship pujant desde baix con easing
|
||||
// [MODIFICAT] Ambas naves usan ease_out_quad (desfase temporal via INIT/END)
|
||||
|
||||
// Aplicar easing (uniforme para ambas naves)
|
||||
float eased_progress = Easing::ease_out_quad(progress);
|
||||
|
||||
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
|
||||
|
||||
// Calcular posición final segons player (reutilitza obtenir_punt_spawn)
|
||||
Vec2 spawn_final = obtenir_punt_spawn(player_id);
|
||||
float x_final = spawn_final.x;
|
||||
float y_final = spawn_final.y;
|
||||
|
||||
// Y inicial: offscreen, 50px sota la zona de juego
|
||||
float y_inicial = zona.y + zona.h + 50.0F;
|
||||
|
||||
// X no canvia (destí segons player_id)
|
||||
// Y interpola con easing
|
||||
float y_animada = y_inicial + ((y_final - y_inicial) * eased_progress);
|
||||
|
||||
return {.x = x_final, .y = y_animada};
|
||||
}
|
||||
|
||||
float GameScene::calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const {
|
||||
// Convierte global_progress (0.0→1.0) a element_progress usando ventana [INIT, END]
|
||||
//
|
||||
// Casos:
|
||||
// - global_progress < INIT → 0.0 (no ha empezado)
|
||||
// - global_progress > END → 1.0 (completado)
|
||||
// - INIT ≤ global_progress ≤ END → interpola linealmente 0.0→1.0
|
||||
|
||||
// Validación de parámetros (evita división por cero)
|
||||
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;
|
||||
}
|
||||
|
||||
// Normalizar rango [INIT, END] a [0.0, 1.0]
|
||||
return (global_progress - ratio_init) / (ratio_end - ratio_init);
|
||||
}
|
||||
|
||||
std::string GameScene::buildScoreboard() const {
|
||||
// Puntuación P1 (6 dígits) - mostrar zeros si inactiu
|
||||
std::string score_p1;
|
||||
|
||||
Reference in New Issue
Block a user