animacions de INIT_HUD amb control d'inici i final

This commit is contained in:
2025-12-16 09:39:53 +01:00
parent 8b896912b2
commit c959e0e3a0
4 changed files with 139 additions and 46 deletions

View File

@@ -160,10 +160,10 @@ void EscenaJoc::inicialitzar() {
puntuacio_per_jugador_[1] = 0;
gestor_puntuacio_.reiniciar();
// Set spawn point to center X, 75% Y (legacy, for INIT_HUD animation)
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
punt_spawn_.x = zona.x + zona.w * 0.5f;
punt_spawn_.y = zona.y + zona.h * Defaults::Game::INIT_HUD_SHIP_START_Y_RATIO;
// DEPRECATED: punt_spawn_ ja no s'usa, es calcula dinàmicament amb obtenir_punt_spawn(player_id)
// const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
// punt_spawn_.x = zona.x + zona.w * 0.5f;
// punt_spawn_.y = zona.y + zona.h * Defaults::Game::INIT_HUD_SHIP_START_Y_RATIO;
// Inicialitzar naus segons configuració (només jugadors actius)
for (uint8_t i = 0; i < 2; i++) {
@@ -318,22 +318,33 @@ void EscenaJoc::actualitzar(float delta_time) {
break;
}
// Calcular progrés de l'animació de la nau
float ship_progress = 1.0f - (stage_manager_->get_timer_transicio() /
Defaults::Game::INIT_HUD_DURATION);
ship_progress = std::min(1.0f, ship_progress);
// Calcular global progress (0.0 al inicio → 1.0 al final)
float global_progress = 1.0f - (stage_manager_->get_timer_transicio() /
Defaults::Game::INIT_HUD_DURATION);
global_progress = std::min(1.0f, global_progress);
// Calcular quant ha avançat l'animació de la nau
float ship_anim_progress = ship_progress / Defaults::Game::INIT_HUD_SHIP_RATIO;
ship_anim_progress = std::min(1.0f, ship_anim_progress);
// [NEW] Calcular progress independiente para cada nave
float ship1_progress = calcular_progress_rango(
global_progress,
Defaults::Game::INIT_HUD_SHIP1_RATIO_INIT,
Defaults::Game::INIT_HUD_SHIP1_RATIO_END
);
// [NOU] Determinar quina nau ha d'animar-se (jugador actiu)
uint8_t ship_to_animate = config_partida_.jugador1_actiu ? 0 : 1;
float ship2_progress = calcular_progress_rango(
global_progress,
Defaults::Game::INIT_HUD_SHIP2_RATIO_INIT,
Defaults::Game::INIT_HUD_SHIP2_RATIO_END
);
// Actualitzar posició de la nau activa segons animació
if (ship_anim_progress < 1.0f) {
Punt pos_animada = calcular_posicio_nau_init_hud(ship_anim_progress);
naus_[ship_to_animate].set_centre(pos_animada); // Nau del jugador actiu
// [MODIFICAT] Animar AMBAS naus con sus progress respectivos
if (config_partida_.jugador1_actiu && ship1_progress < 1.0f) {
Punt pos_p1 = calcular_posicio_nau_init_hud(ship1_progress, 0);
naus_[0].set_centre(pos_p1);
}
if (config_partida_.jugador2_actiu && ship2_progress < 1.0f) {
Punt pos_p2 = calcular_posicio_nau_init_hud(ship2_progress, 1);
naus_[1].set_centre(pos_p2);
}
// Una vegada l'animació acaba, permetre control normal
@@ -482,17 +493,30 @@ void EscenaJoc::dibuixar() {
float total_time = Defaults::Game::INIT_HUD_DURATION;
float global_progress = 1.0f - (timer / total_time);
// Progrés del rectangle (empieza inmediatament)
float rect_progress = global_progress / Defaults::Game::INIT_HUD_RECT_RATIO;
rect_progress = std::min(1.0f, rect_progress);
// [NEW] Calcular progress independiente para cada elemento
float rect_progress = calcular_progress_rango(
global_progress,
Defaults::Game::INIT_HUD_RECT_RATIO_INIT,
Defaults::Game::INIT_HUD_RECT_RATIO_END
);
// Progrés del marcador (empieza inmediatament)
float score_progress = global_progress / Defaults::Game::INIT_HUD_SCORE_RATIO;
score_progress = std::min(1.0f, score_progress);
float score_progress = calcular_progress_rango(
global_progress,
Defaults::Game::INIT_HUD_SCORE_RATIO_INIT,
Defaults::Game::INIT_HUD_SCORE_RATIO_END
);
// Progrés de la nau (empieza inmediatament)
float ship_progress = global_progress / Defaults::Game::INIT_HUD_SHIP_RATIO;
ship_progress = std::min(1.0f, ship_progress);
float ship1_progress = calcular_progress_rango(
global_progress,
Defaults::Game::INIT_HUD_SHIP1_RATIO_INIT,
Defaults::Game::INIT_HUD_SHIP1_RATIO_END
);
float ship2_progress = calcular_progress_rango(
global_progress,
Defaults::Game::INIT_HUD_SHIP2_RATIO_INIT,
Defaults::Game::INIT_HUD_SHIP2_RATIO_END
);
// Dibuixar elements animats
if (rect_progress > 0.0f) {
@@ -503,10 +527,13 @@ void EscenaJoc::dibuixar() {
dibuixar_marcador_animat(score_progress);
}
// Dibuixar nau del jugador actiu (posició ja actualitzada en actualitzar())
uint8_t ship_to_draw = config_partida_.jugador1_actiu ? 0 : 1;
if (ship_progress > 0.0f && !naus_[ship_to_draw].esta_tocada()) {
naus_[ship_to_draw].dibuixar();
// [MODIFICAT] Dibuixar naus amb progress independent
if (ship1_progress > 0.0f && config_partida_.jugador1_actiu && !naus_[0].esta_tocada()) {
naus_[0].dibuixar();
}
if (ship2_progress > 0.0f && config_partida_.jugador2_actiu && !naus_[1].esta_tocada()) {
naus_[1].dibuixar();
}
break;
@@ -759,30 +786,55 @@ void EscenaJoc::dibuixar_marcador_animat(float progress) {
text_.render(text, {x_final, y_animada}, escala, spacing);
}
Punt EscenaJoc::calcular_posicio_nau_init_hud(float progress) const {
Punt EscenaJoc::calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const {
// Animació de la nau pujant des de baix amb easing
// [MODIFICAT] Ambas naves usan ease_out_quad (desfase temporal via INIT/END)
// Calcular progrés amb easing
// Aplicar easing (uniforme para ambas naves)
float eased_progress = Easing::ease_out_quad(progress);
const SDL_FRect& zona = Defaults::Zones::PLAYAREA;
// Posició X final (centre de la zona de joc)
float x_final = zona.x + zona.w / 2.0f;
// Calcular posició final segons jugador (reutilitza obtenir_punt_spawn)
Punt spawn_final = obtenir_punt_spawn(player_id);
float x_final = spawn_final.x;
float y_final = spawn_final.y;
// Posició Y final (75% de l'altura de la zona de joc)
float y_final = zona.y + zona.h * Defaults::Game::INIT_HUD_SHIP_START_Y_RATIO;
// Y inicial: offscreen, 50px sota la zona de joc
float y_inicial = zona.y + zona.h + 50.0f;
// Posició Y inicial (offscreen, sota de la zona de joc)
float y_inicial = zona.y + zona.h + 50.0f; // 50px sota
// X no canvia (sempre centrada)
// X no canvia (destí segons player_id)
// Y interpola amb easing
float y_animada = y_inicial + (y_final - y_inicial) * eased_progress;
return {x_final, y_animada};
}
float EscenaJoc::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 EscenaJoc::construir_marcador() const {
// Puntuació P1 (6 dígits) - mostrar zeros si inactiu
std::string score_p1;