animacio del titol als 10 segons
This commit is contained in:
@@ -25,7 +25,11 @@ EscenaTitol::EscenaTitol(SDLManager& sdl)
|
|||||||
: sdl_(sdl),
|
: sdl_(sdl),
|
||||||
text_(sdl.obte_renderer()),
|
text_(sdl.obte_renderer()),
|
||||||
estat_actual_(EstatTitol::INIT),
|
estat_actual_(EstatTitol::INIT),
|
||||||
temps_acumulat_(0.0f) {
|
temps_acumulat_(0.0f),
|
||||||
|
temps_animacio_(0.0f),
|
||||||
|
temps_estat_main_(0.0f),
|
||||||
|
animacio_activa_(false),
|
||||||
|
factor_lerp_(0.0f) {
|
||||||
std::cout << "Escena Titol: Inicialitzant...\n";
|
std::cout << "Escena Titol: Inicialitzant...\n";
|
||||||
|
|
||||||
// Crear starfield de fons
|
// Crear starfield de fons
|
||||||
@@ -198,6 +202,19 @@ void EscenaTitol::inicialitzar_titol() {
|
|||||||
|
|
||||||
std::cout << "[EscenaTitol] Línia 2 (ATTACK!): " << lletres_attack_.size()
|
std::cout << "[EscenaTitol] Línia 2 (ATTACK!): " << lletres_attack_.size()
|
||||||
<< " lletres, ancho total: " << ancho_total_attack << " px\n";
|
<< " lletres, ancho total: " << ancho_total_attack << " px\n";
|
||||||
|
|
||||||
|
// Guardar posicions originals per l'animació orbital
|
||||||
|
posicions_originals_orni_.clear();
|
||||||
|
for (const auto& lletra : lletres_orni_) {
|
||||||
|
posicions_originals_orni_.push_back(lletra.posicio);
|
||||||
|
}
|
||||||
|
|
||||||
|
posicions_originals_attack_.clear();
|
||||||
|
for (const auto& lletra : lletres_attack_) {
|
||||||
|
posicions_originals_attack_.push_back(lletra.posicio);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "[EscenaTitol] Animació: Posicions originals guardades\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void EscenaTitol::executar() {
|
void EscenaTitol::executar() {
|
||||||
@@ -273,12 +290,60 @@ void EscenaTitol::actualitzar(float delta_time) {
|
|||||||
temps_acumulat_ += delta_time;
|
temps_acumulat_ += delta_time;
|
||||||
if (temps_acumulat_ >= DURACIO_INIT) {
|
if (temps_acumulat_ >= DURACIO_INIT) {
|
||||||
estat_actual_ = EstatTitol::MAIN;
|
estat_actual_ = EstatTitol::MAIN;
|
||||||
|
temps_estat_main_ = 0.0f; // Reset timer al entrar a MAIN
|
||||||
|
animacio_activa_ = false; // Comença estàtic
|
||||||
|
factor_lerp_ = 0.0f; // Sense animació encara
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EstatTitol::MAIN:
|
case EstatTitol::MAIN: {
|
||||||
// No hi ha lògica d'actualització en l'estat MAIN
|
temps_estat_main_ += delta_time;
|
||||||
|
|
||||||
|
// Fase 1: Estàtic (0-10s)
|
||||||
|
if (temps_estat_main_ < DELAY_INICI_ANIMACIO) {
|
||||||
|
factor_lerp_ = 0.0f;
|
||||||
|
animacio_activa_ = false;
|
||||||
|
}
|
||||||
|
// Fase 2: Lerp (10-12s)
|
||||||
|
else if (temps_estat_main_ < DELAY_INICI_ANIMACIO + DURACIO_LERP) {
|
||||||
|
float temps_lerp = temps_estat_main_ - DELAY_INICI_ANIMACIO;
|
||||||
|
factor_lerp_ = temps_lerp / DURACIO_LERP; // 0.0 → 1.0 linealment
|
||||||
|
animacio_activa_ = true;
|
||||||
|
}
|
||||||
|
// Fase 3: Animació completa (12s+)
|
||||||
|
else {
|
||||||
|
factor_lerp_ = 1.0f;
|
||||||
|
animacio_activa_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Acumular temps escalat directament
|
||||||
|
if (animacio_activa_) {
|
||||||
|
temps_animacio_ += delta_time * factor_lerp_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Usar amplituds i freqüències completes sempre
|
||||||
|
float amplitude_x_actual = ORBIT_AMPLITUDE_X;
|
||||||
|
float amplitude_y_actual = ORBIT_AMPLITUDE_Y;
|
||||||
|
float frequency_x_actual = ORBIT_FREQUENCY_X;
|
||||||
|
float frequency_y_actual = ORBIT_FREQUENCY_Y;
|
||||||
|
|
||||||
|
// Calcular offset orbital
|
||||||
|
float offset_x = amplitude_x_actual * std::sin(2.0f * Defaults::Math::PI * frequency_x_actual * temps_animacio_);
|
||||||
|
float offset_y = amplitude_y_actual * std::sin(2.0f * Defaults::Math::PI * frequency_y_actual * temps_animacio_ + ORBIT_PHASE_OFFSET);
|
||||||
|
|
||||||
|
// Aplicar offset a totes les lletres de "ORNI"
|
||||||
|
for (size_t i = 0; i < lletres_orni_.size(); ++i) {
|
||||||
|
lletres_orni_[i].posicio.x = posicions_originals_orni_[i].x + static_cast<int>(std::round(offset_x));
|
||||||
|
lletres_orni_[i].posicio.y = posicions_originals_orni_[i].y + static_cast<int>(std::round(offset_y));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aplicar offset a totes les lletres de "ATTACK!"
|
||||||
|
for (size_t i = 0; i < lletres_attack_.size(); ++i) {
|
||||||
|
lletres_attack_[i].posicio.x = posicions_originals_attack_[i].x + static_cast<int>(std::round(offset_x));
|
||||||
|
lletres_attack_[i].posicio.y = posicions_originals_attack_[i].y + static_cast<int>(std::round(offset_y));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case EstatTitol::TRANSITION:
|
case EstatTitol::TRANSITION:
|
||||||
temps_acumulat_ += delta_time;
|
temps_acumulat_ += delta_time;
|
||||||
@@ -303,7 +368,63 @@ void EscenaTitol::dibuixar() {
|
|||||||
|
|
||||||
// Estat MAIN i TRANSITION: Dibuixar títol i text (sobre el starfield)
|
// Estat MAIN i TRANSITION: Dibuixar títol i text (sobre el starfield)
|
||||||
if (estat_actual_ == EstatTitol::MAIN || estat_actual_ == EstatTitol::TRANSITION) {
|
if (estat_actual_ == EstatTitol::MAIN || estat_actual_ == EstatTitol::TRANSITION) {
|
||||||
// === Dibuixar lletres del títol "ORNI ATTACK!" ===
|
// === Calcular i renderitzar ombra (només si animació activa) ===
|
||||||
|
if (animacio_activa_) {
|
||||||
|
float temps_shadow = temps_animacio_ - SHADOW_DELAY;
|
||||||
|
if (temps_shadow < 0.0f) temps_shadow = 0.0f; // Evitar temps negatiu
|
||||||
|
|
||||||
|
// Usar amplituds i freqüències completes per l'ombra
|
||||||
|
float amplitude_x_shadow = ORBIT_AMPLITUDE_X;
|
||||||
|
float amplitude_y_shadow = ORBIT_AMPLITUDE_Y;
|
||||||
|
float frequency_x_shadow = ORBIT_FREQUENCY_X;
|
||||||
|
float frequency_y_shadow = ORBIT_FREQUENCY_Y;
|
||||||
|
|
||||||
|
// Calcular offset de l'ombra
|
||||||
|
float shadow_offset_x = amplitude_x_shadow * std::sin(2.0f * Defaults::Math::PI * frequency_x_shadow * temps_shadow)
|
||||||
|
+ SHADOW_OFFSET_X;
|
||||||
|
float shadow_offset_y = amplitude_y_shadow * std::sin(2.0f * Defaults::Math::PI * frequency_y_shadow * temps_shadow + ORBIT_PHASE_OFFSET)
|
||||||
|
+ SHADOW_OFFSET_Y;
|
||||||
|
|
||||||
|
// === RENDERITZAR OMBRA PRIMER (darrera del logo principal) ===
|
||||||
|
|
||||||
|
// Ombra "ORNI"
|
||||||
|
for (size_t i = 0; i < lletres_orni_.size(); ++i) {
|
||||||
|
Punt pos_shadow;
|
||||||
|
pos_shadow.x = posicions_originals_orni_[i].x + static_cast<int>(std::round(shadow_offset_x));
|
||||||
|
pos_shadow.y = posicions_originals_orni_[i].y + static_cast<int>(std::round(shadow_offset_y));
|
||||||
|
|
||||||
|
Rendering::render_shape(
|
||||||
|
sdl_.obte_renderer(),
|
||||||
|
lletres_orni_[i].forma,
|
||||||
|
pos_shadow,
|
||||||
|
0.0f,
|
||||||
|
ESCALA_TITULO,
|
||||||
|
true,
|
||||||
|
1.0f, // progress = 1.0 (totalment visible)
|
||||||
|
SHADOW_BRIGHTNESS // brightness = 0.4 (brillantor reduïda)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ombra "ATTACK!"
|
||||||
|
for (size_t i = 0; i < lletres_attack_.size(); ++i) {
|
||||||
|
Punt pos_shadow;
|
||||||
|
pos_shadow.x = posicions_originals_attack_[i].x + static_cast<int>(std::round(shadow_offset_x));
|
||||||
|
pos_shadow.y = posicions_originals_attack_[i].y + static_cast<int>(std::round(shadow_offset_y));
|
||||||
|
|
||||||
|
Rendering::render_shape(
|
||||||
|
sdl_.obte_renderer(),
|
||||||
|
lletres_attack_[i].forma,
|
||||||
|
pos_shadow,
|
||||||
|
0.0f,
|
||||||
|
ESCALA_TITULO,
|
||||||
|
true,
|
||||||
|
1.0f, // progress = 1.0 (totalment visible)
|
||||||
|
SHADOW_BRIGHTNESS
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === RENDERITZAR LOGO PRINCIPAL (damunt) ===
|
||||||
|
|
||||||
// Dibuixar "ORNI" (línia 1)
|
// Dibuixar "ORNI" (línia 1)
|
||||||
for (const auto& lletra : lletres_orni_) {
|
for (const auto& lletra : lletres_orni_) {
|
||||||
@@ -311,10 +432,10 @@ void EscenaTitol::dibuixar() {
|
|||||||
sdl_.obte_renderer(),
|
sdl_.obte_renderer(),
|
||||||
lletra.forma,
|
lletra.forma,
|
||||||
lletra.posicio,
|
lletra.posicio,
|
||||||
0.0f, // sense rotació
|
0.0f,
|
||||||
ESCALA_TITULO, // escala 80%
|
ESCALA_TITULO,
|
||||||
true, // dibuixar
|
true,
|
||||||
1.0f // progrés complet (totalment visible)
|
1.0f // Brillantor completa
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,10 +445,10 @@ void EscenaTitol::dibuixar() {
|
|||||||
sdl_.obte_renderer(),
|
sdl_.obte_renderer(),
|
||||||
lletra.forma,
|
lletra.forma,
|
||||||
lletra.posicio,
|
lletra.posicio,
|
||||||
0.0f, // sense rotació
|
0.0f,
|
||||||
ESCALA_TITULO, // escala 80%
|
ESCALA_TITULO,
|
||||||
true, // dibuixar
|
true,
|
||||||
1.0f // progrés complet (totalment visible)
|
1.0f // Brillantor completa
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,16 @@ class EscenaTitol {
|
|||||||
std::vector<LetraLogo> lletres_attack_; // Lletres de "ATTACK!" (línia 2)
|
std::vector<LetraLogo> lletres_attack_; // Lletres de "ATTACK!" (línia 2)
|
||||||
float y_attack_dinamica_; // Posició Y calculada dinàmicament per "ATTACK!"
|
float y_attack_dinamica_; // Posició Y calculada dinàmicament per "ATTACK!"
|
||||||
|
|
||||||
|
// Estat d'animació del logo
|
||||||
|
float temps_animacio_; // Temps acumulat per animació orbital
|
||||||
|
std::vector<Punt> posicions_originals_orni_; // Posicions originals de "ORNI"
|
||||||
|
std::vector<Punt> posicions_originals_attack_; // Posicions originals de "ATTACK!"
|
||||||
|
|
||||||
|
// Estat d'arrencada de l'animació
|
||||||
|
float temps_estat_main_; // Temps acumulat en estat MAIN
|
||||||
|
bool animacio_activa_; // Flag: true quan animació està activa
|
||||||
|
float factor_lerp_; // Factor de lerp actual (0.0 → 1.0)
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
static constexpr float DURACIO_INIT = 4.0f; // Duració de l'estat INIT (2 segons)
|
static constexpr float DURACIO_INIT = 4.0f; // Duració de l'estat INIT (2 segons)
|
||||||
static constexpr float DURACIO_TRANSITION = 1.5f; // Duració de la transició (1.5 segons)
|
static constexpr float DURACIO_TRANSITION = 1.5f; // Duració de la transició (1.5 segons)
|
||||||
@@ -60,6 +70,23 @@ class EscenaTitol {
|
|||||||
static constexpr float BLINK_FREQUENCY = 3.0f; // Freqüència de parpelleig (3 Hz)
|
static constexpr float BLINK_FREQUENCY = 3.0f; // Freqüència de parpelleig (3 Hz)
|
||||||
static constexpr int MUSIC_FADE = 1000; // Duracio del fade de la musica del titol al començar a jugar
|
static constexpr int MUSIC_FADE = 1000; // Duracio del fade de la musica del titol al començar a jugar
|
||||||
|
|
||||||
|
// Constants d'animació del logo
|
||||||
|
static constexpr float ORBIT_AMPLITUDE_X = 2.0f*2; // Amplitud oscil·lació horitzontal (píxels)
|
||||||
|
static constexpr float ORBIT_AMPLITUDE_Y = 1.5f*2; // Amplitud oscil·lació vertical (píxels)
|
||||||
|
static constexpr float ORBIT_FREQUENCY_X = 0.8f; // Velocitat oscil·lació horitzontal (Hz)
|
||||||
|
static constexpr float ORBIT_FREQUENCY_Y = 1.2f; // Velocitat oscil·lació vertical (Hz)
|
||||||
|
static constexpr float ORBIT_PHASE_OFFSET = 1.57f; // Desfasament entre X i Y (90° per circular)
|
||||||
|
|
||||||
|
// Constants d'ombra del logo
|
||||||
|
static constexpr float SHADOW_DELAY = 0.5f; // Retard temporal de l'ombra (segons)
|
||||||
|
static constexpr float SHADOW_BRIGHTNESS = 0.4f; // Multiplicador de brillantor de l'ombra (0.0-1.0)
|
||||||
|
static constexpr float SHADOW_OFFSET_X = 2.0f; // Offset espacial X fix (píxels)
|
||||||
|
static constexpr float SHADOW_OFFSET_Y = 2.0f; // Offset espacial Y fix (píxels)
|
||||||
|
|
||||||
|
// Temporització de l'arrencada de l'animació
|
||||||
|
static constexpr float DELAY_INICI_ANIMACIO = 10.0f; // 10s estàtic abans d'animar
|
||||||
|
static constexpr float DURACIO_LERP = 2.0f; // 2s per arribar a amplitud completa
|
||||||
|
|
||||||
// Mètodes privats
|
// Mètodes privats
|
||||||
void actualitzar(float delta_time);
|
void actualitzar(float delta_time);
|
||||||
void dibuixar();
|
void dibuixar();
|
||||||
|
|||||||
Reference in New Issue
Block a user