animacions de INIT_HUD amb control d'inici i final
This commit is contained in:
@@ -132,9 +132,23 @@ constexpr float LEVEL_COMPLETED_TYPING_RATIO = 0.0f; // 0.0 = sin typewriter (d
|
||||
|
||||
// Transición INIT_HUD (animación inicial del HUD)
|
||||
constexpr float INIT_HUD_DURATION = 3.0f; // Duración total del estado
|
||||
constexpr float INIT_HUD_RECT_RATIO = 0.67f; // Proporción animación rectángulo
|
||||
constexpr float INIT_HUD_SCORE_RATIO = 0.83f; // Proporción animación marcador
|
||||
constexpr float INIT_HUD_SHIP_RATIO = 1.0f; // Proporción animación nave
|
||||
|
||||
// Ratios de animación (inicio y fin como porcentajes del tiempo total)
|
||||
// RECT (rectángulo de marges)
|
||||
constexpr float INIT_HUD_RECT_RATIO_INIT = 0.33f;
|
||||
constexpr float INIT_HUD_RECT_RATIO_END = 1.0f;
|
||||
|
||||
// SCORE (marcador de puntuación)
|
||||
constexpr float INIT_HUD_SCORE_RATIO_INIT = 0.17f;
|
||||
constexpr float INIT_HUD_SCORE_RATIO_END = 1.0f;
|
||||
|
||||
// SHIP1 (nave jugador 1)
|
||||
constexpr float INIT_HUD_SHIP1_RATIO_INIT = 0.0f;
|
||||
constexpr float INIT_HUD_SHIP1_RATIO_END = 1.0f;
|
||||
|
||||
// SHIP2 (nave jugador 2)
|
||||
constexpr float INIT_HUD_SHIP2_RATIO_INIT = 0.20f;
|
||||
constexpr float INIT_HUD_SHIP2_RATIO_END = 1.0f;
|
||||
|
||||
// Posición inicial de la nave en INIT_HUD (75% de altura de zona de juego)
|
||||
constexpr float INIT_HUD_SHIP_START_Y_RATIO = 0.75f; // 75% desde el top de PLAYAREA
|
||||
|
||||
@@ -12,6 +12,30 @@ inline float ease_out_quad(float t) {
|
||||
return 1.0f - (1.0f - t) * (1.0f - t);
|
||||
}
|
||||
|
||||
// Ease-in quadratic: empieza lento, acelera
|
||||
// t = progreso normalizado [0.0 - 1.0]
|
||||
// retorna valor interpolado [0.0 - 1.0]
|
||||
inline float ease_in_quad(float t) {
|
||||
return t * t;
|
||||
}
|
||||
|
||||
// Ease-in-out quadratic: acelera al inicio, desacelera al final
|
||||
// t = progreso normalizado [0.0 - 1.0]
|
||||
// retorna valor interpolado [0.0 - 1.0]
|
||||
inline float ease_in_out_quad(float t) {
|
||||
return (t < 0.5f)
|
||||
? 2.0f * t * t
|
||||
: 1.0f - (-2.0f * t + 2.0f) * (-2.0f * t + 2.0f) / 2.0f;
|
||||
}
|
||||
|
||||
// Ease-out cubic: desaceleración más suave que quadratic
|
||||
// t = progreso normalizado [0.0 - 1.0]
|
||||
// retorna valor interpolado [0.0 - 1.0]
|
||||
inline float ease_out_cubic(float t) {
|
||||
float t1 = 1.0f - t;
|
||||
return 1.0f - t1 * t1 * t1;
|
||||
}
|
||||
|
||||
// Interpolación lineal básica (para referencia)
|
||||
inline float lerp(float start, float end, float t) {
|
||||
return start + (end - start) * t;
|
||||
|
||||
@@ -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() /
|
||||
// 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);
|
||||
ship_progress = std::min(1.0f, ship_progress);
|
||||
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;
|
||||
|
||||
@@ -56,7 +56,7 @@ class EscenaJoc {
|
||||
std::array<int, 2> vides_per_jugador_; // [0]=P1, [1]=P2
|
||||
bool game_over_; // Game over state flag
|
||||
float game_over_timer_; // Countdown timer for auto-return (seconds)
|
||||
Punt punt_spawn_; // Configurable spawn point (legacy)
|
||||
// Punt punt_spawn_; // DEPRECATED: usar obtenir_punt_spawn(player_id)
|
||||
Punt punt_mort_; // Death position (for respawn, legacy)
|
||||
std::array<int, 2> puntuacio_per_jugador_; // [0]=P1, [1]=P2
|
||||
|
||||
@@ -82,7 +82,10 @@ class EscenaJoc {
|
||||
// [NEW] Funcions d'animació per INIT_HUD
|
||||
void dibuixar_marges_animat(float progress) const; // Rectangle amb creixement uniforme
|
||||
void dibuixar_marcador_animat(float progress); // Marcador que puja des de baix
|
||||
Punt calcular_posicio_nau_init_hud(float progress) const; // Posició animada de la nau
|
||||
Punt calcular_posicio_nau_init_hud(float progress, uint8_t player_id) const; // Posició animada de la nau
|
||||
|
||||
// [NEW] Función helper del sistema de animación INIT_HUD
|
||||
float calcular_progress_rango(float global_progress, float ratio_init, float ratio_end) const;
|
||||
|
||||
// [NEW] Funció helper del marcador
|
||||
std::string construir_marcador() const;
|
||||
|
||||
Reference in New Issue
Block a user