intro acabada

This commit is contained in:
2026-04-03 20:40:54 +02:00
parent ce2fcefd71
commit 5f7fb8625d
6 changed files with 106 additions and 67 deletions

View File

@@ -90,7 +90,7 @@ service_menu.window_message.text_safety_margin 15.0f # Margen de segu
service_menu.window_message.animation_duration 0.3f # Duración de animaciones de ventanas (segundos) service_menu.window_message.animation_duration 0.3f # Duración de animaciones de ventanas (segundos)
# --- INTRO --- # --- INTRO ---
intro.bg_color 4664BD # Color de fondo de la intro intro.bg_color 41526F # Color de fondo de la intro
intro.card_color CBDBFC # Color de las tarjetas en la intro intro.card_color CBDBFC # Color de las tarjetas en la intro
intro.shadow_color 00000080 # Color de la sombra de las tarjetas en la intro intro.shadow_color 00000080 # Color de la sombra de las tarjetas en la intro
intro.text_distance_from_bottom 48 # Posicion del texto intro.text_distance_from_bottom 48 # Posicion del texto

View File

@@ -90,7 +90,7 @@ service_menu.window_message.text_safety_margin 15.0f # Margen de segu
service_menu.window_message.animation_duration 0.3f # Duración de animaciones de ventanas (segundos) service_menu.window_message.animation_duration 0.3f # Duración de animaciones de ventanas (segundos)
# --- INTRO --- # --- INTRO ---
intro.bg_color 4664BD # Color de fondo de la intro intro.bg_color 41526F # Color de fondo de la intro
intro.card_color CBDBFC # Color de las tarjetas en la intro intro.card_color CBDBFC # Color de las tarjetas en la intro
intro.shadow_color 00000080 # Color de la sombra de las tarjetas en la intro intro.shadow_color 00000080 # Color de la sombra de las tarjetas en la intro
intro.text_distance_from_bottom 48 # Posición del texto desde la parte inferior intro.text_distance_from_bottom 48 # Posición del texto desde la parte inferior

View File

@@ -13,9 +13,9 @@ CardSprite::CardSprite(std::shared_ptr<Texture> texture)
entry_easing_(easeOutBounce) {} entry_easing_(easeOutBounce) {}
// Inicia la animación de entrada (solo si está en IDLE) // Inicia la animación de entrada (solo si está en IDLE)
void CardSprite::enable() { auto CardSprite::enable() -> bool {
if (state_ != CardState::IDLE) { if (state_ != CardState::IDLE) {
return; return false;
} }
state_ = CardState::ENTERING; state_ = CardState::ENTERING;
@@ -34,6 +34,7 @@ void CardSprite::enable() {
rotate_.center = {pos_.w / 2.0F, pos_.h / 2.0F}; rotate_.center = {pos_.w / 2.0F, pos_.h / 2.0F};
shadow_visible_ = true; shadow_visible_ = true;
return true;
} }
// Inicia la animación de salida (solo si está en LANDED) // Inicia la animación de salida (solo si está en LANDED)
@@ -43,7 +44,7 @@ void CardSprite::startExit() {
} }
state_ = CardState::EXITING; state_ = CardState::EXITING;
shadow_visible_ = false; shadow_visible_ = true;
// Velocidad y aceleración de salida // Velocidad y aceleración de salida
vx_ = exit_vx_; vx_ = exit_vx_;
@@ -109,11 +110,21 @@ void CardSprite::updateEntering(float delta_time) {
} }
} }
// Animación de salida: movimiento + rotación continua // Animación de salida: movimiento + rotación continua + zoom opcional
void CardSprite::updateExiting(float delta_time) { void CardSprite::updateExiting(float delta_time) {
move(delta_time); move(delta_time);
rotate(delta_time); rotate(delta_time);
// Ganar altura gradualmente (zoom hacia el objetivo)
if (exit_zoom_speed_ > 0.0F && horizontal_zoom_ < exit_target_zoom_) {
float new_zoom = horizontal_zoom_ + exit_zoom_speed_ * delta_time;
if (new_zoom > exit_target_zoom_) {
new_zoom = exit_target_zoom_;
}
horizontal_zoom_ = new_zoom;
vertical_zoom_ = new_zoom;
}
if (isOffScreen()) { if (isOffScreen()) {
state_ = CardState::FINISHED; state_ = CardState::FINISHED;
} }
@@ -153,9 +164,8 @@ void CardSprite::renderShadow() {
// Offset respecto a la tarjeta: base + extra proporcional a la altura // Offset respecto a la tarjeta: base + extra proporcional a la altura
// La sombra se aleja en diagonal abajo-derecha (opuesta a la luz en 0,0) // La sombra se aleja en diagonal abajo-derecha (opuesta a la luz en 0,0)
static constexpr float HEIGHT_MULTIPLIER = 300.0F; float offset_x = shadow_offset_x_ + height * SHADOW_HEIGHT_MULTIPLIER;
float offset_x = shadow_offset_x_ + height * HEIGHT_MULTIPLIER; float offset_y = shadow_offset_y_ + height * SHADOW_HEIGHT_MULTIPLIER;
float offset_y = shadow_offset_y_ + height * HEIGHT_MULTIPLIER;
shadow_texture_->render( shadow_texture_->render(
pos_.x + offset_x, pos_.x + offset_x,
@@ -163,8 +173,8 @@ void CardSprite::renderShadow() {
&sprite_clip_, &sprite_clip_,
shadow_zoom, shadow_zoom,
shadow_zoom, shadow_zoom,
0.0, rotate_.angle,
nullptr, &rotate_.center,
flip_); flip_);
} }
@@ -225,6 +235,11 @@ void CardSprite::setExitParams(float vx, float vy, float ax, float ay, double ro
exit_rotate_amount_ = rotate_amount; exit_rotate_amount_ = rotate_amount;
} }
void CardSprite::setExitLift(float target_zoom, float zoom_speed) {
exit_target_zoom_ = target_zoom;
exit_zoom_speed_ = zoom_speed;
}
void CardSprite::setShadowTexture(std::shared_ptr<Texture> texture) { void CardSprite::setShadowTexture(std::shared_ptr<Texture> texture) {
shadow_texture_ = std::move(texture); shadow_texture_ = std::move(texture);
} }

View File

@@ -33,7 +33,7 @@ class CardSprite : public MovingSprite {
void render() override; void render() override;
// --- Control de estado --- // --- Control de estado ---
void enable(); // Inicia la animación de entrada auto enable() -> bool; // Inicia la animación de entrada (true si se activó)
void startExit(); // Inicia la animación de salida void startExit(); // Inicia la animación de salida
// --- Consultas de estado --- // --- Consultas de estado ---
@@ -50,6 +50,7 @@ class CardSprite : public MovingSprite {
// --- Configuración de salida --- // --- Configuración de salida ---
void setExitParams(float vx, float vy, float ax, float ay, double rotate_amount); void setExitParams(float vx, float vy, float ax, float ay, double rotate_amount);
void setExitLift(float target_zoom, float zoom_speed); // Ganar altura al salir (zoom > 1.0)
// --- Sombra --- // --- Sombra ---
void setShadowTexture(std::shared_ptr<Texture> texture); void setShadowTexture(std::shared_ptr<Texture> texture);
@@ -83,6 +84,8 @@ class CardSprite : public MovingSprite {
float exit_ax_ = 0.0F; float exit_ax_ = 0.0F;
float exit_ay_ = 0.0F; float exit_ay_ = 0.0F;
double exit_rotate_amount_ = 0.0; double exit_rotate_amount_ = 0.0;
float exit_target_zoom_ = 1.0F; // Zoom objetivo al salir (>1.0 = se eleva)
float exit_zoom_speed_ = 0.0F; // Velocidad de cambio de zoom por segundo
// --- Sombra --- // --- Sombra ---
std::shared_ptr<Texture> shadow_texture_; std::shared_ptr<Texture> shadow_texture_;
@@ -94,8 +97,9 @@ class CardSprite : public MovingSprite {
float screen_width_ = 320.0F; float screen_width_ = 320.0F;
float screen_height_ = 240.0F; float screen_height_ = 240.0F;
// --- Margen fuera de pantalla para considerar FINISHED --- // --- Constantes ---
static constexpr float OFF_SCREEN_MARGIN = 50.0F; static constexpr float OFF_SCREEN_MARGIN = 50.0F; // Margen fuera de pantalla para considerar FINISHED
static constexpr float SHADOW_HEIGHT_MULTIPLIER = 400.0F; // Pixels de separación de sombra por unidad de altura
// --- Métodos internos --- // --- Métodos internos ---
void updateEntering(float delta_time); void updateEntering(float delta_time);

View File

@@ -57,10 +57,21 @@ void Intro::checkInput() {
// Actualiza las escenas de la intro // Actualiza las escenas de la intro
void Intro::updateScenes() { void Intro::updateScenes() {
// Cuando la tarjeta actual toca la mesa por primera vez, la anterior sale despedida // Sonido al lanzar la tarjeta (enable() devuelve true solo la primera vez)
if (scene_ > 0 && card_sprites_.at(scene_)->hasFirstTouch()) { if (card_sprites_.at(scene_)->enable()) {
Audio::get()->playSound(SFX_CARD_THROW);
}
// Cuando la tarjeta actual toca la mesa por primera vez: shake + sonido + la anterior sale despedida
if (!shake_done_ && card_sprites_.at(scene_)->hasFirstTouch()) {
Screen::get()->shake();
Audio::get()->playSound(SFX_CARD_IMPACT);
shake_done_ = true;
if (scene_ > 0) {
card_sprites_.at(scene_ - 1)->startExit(); card_sprites_.at(scene_ - 1)->startExit();
} }
}
switch (scene_) { switch (scene_) {
case 0: case 0:
@@ -87,9 +98,6 @@ void Intro::updateScenes() {
} }
void Intro::updateScene0() { void Intro::updateScene0() {
// Primera imagen - UPV: activa la tarjeta
card_sprites_.at(0)->enable();
// Primer texto cuando aterriza // Primer texto cuando aterriza
if (card_sprites_.at(0)->hasLanded() && !texts_.at(0)->hasFinished()) { if (card_sprites_.at(0)->hasLanded() && !texts_.at(0)->hasFinished()) {
texts_.at(0)->setEnabled(true); texts_.at(0)->setEnabled(true);
@@ -109,13 +117,11 @@ void Intro::updateScene0() {
if (texts_.at(2)->hasFinished()) { if (texts_.at(2)->hasFinished()) {
texts_.at(2)->setEnabled(false); texts_.at(2)->setEnabled(false);
scene_++; scene_++;
shake_done_ = false;
} }
} }
void Intro::updateScene1() { void Intro::updateScene1() {
// Segunda imagen - Máquina
card_sprites_.at(1)->enable();
// Texto cuando aterriza // Texto cuando aterriza
if (card_sprites_.at(1)->hasLanded() && !texts_.at(3)->hasFinished()) { if (card_sprites_.at(1)->hasLanded() && !texts_.at(3)->hasFinished()) {
texts_.at(3)->setEnabled(true); texts_.at(3)->setEnabled(true);
@@ -125,12 +131,12 @@ void Intro::updateScene1() {
if (texts_.at(3)->hasFinished()) { if (texts_.at(3)->hasFinished()) {
texts_.at(3)->setEnabled(false); texts_.at(3)->setEnabled(false);
scene_++; scene_++;
shake_done_ = false;
} }
} }
void Intro::updateScene2() { void Intro::updateScene2() {
// Tercera imagen - GRITO: tarjeta y texto a la vez // Tercera imagen - GRITO: tarjeta y texto a la vez
card_sprites_.at(2)->enable();
if (!texts_.at(4)->hasFinished()) { if (!texts_.at(4)->hasFinished()) {
texts_.at(4)->setEnabled(true); texts_.at(4)->setEnabled(true);
} }
@@ -139,13 +145,12 @@ void Intro::updateScene2() {
if (card_sprites_.at(2)->hasLanded() && texts_.at(4)->hasFinished()) { if (card_sprites_.at(2)->hasLanded() && texts_.at(4)->hasFinished()) {
texts_.at(4)->setEnabled(false); texts_.at(4)->setEnabled(false);
scene_++; scene_++;
shake_done_ = false;
} }
} }
void Intro::updateScene3() { void Intro::updateScene3() {
// Cuarta imagen - Reflexión // Cuarta imagen - Reflexión
card_sprites_.at(3)->enable();
if (!texts_.at(5)->hasFinished()) { if (!texts_.at(5)->hasFinished()) {
texts_.at(5)->setEnabled(true); texts_.at(5)->setEnabled(true);
} }
@@ -159,13 +164,12 @@ void Intro::updateScene3() {
if (card_sprites_.at(3)->hasLanded() && texts_.at(6)->hasFinished()) { if (card_sprites_.at(3)->hasLanded() && texts_.at(6)->hasFinished()) {
texts_.at(6)->setEnabled(false); texts_.at(6)->setEnabled(false);
scene_++; scene_++;
shake_done_ = false;
} }
} }
void Intro::updateScene4() { void Intro::updateScene4() {
// Quinta imagen - Patada // Quinta imagen - Patada
card_sprites_.at(4)->enable();
if (!texts_.at(7)->hasFinished()) { if (!texts_.at(7)->hasFinished()) {
texts_.at(7)->setEnabled(true); texts_.at(7)->setEnabled(true);
} }
@@ -174,13 +178,12 @@ void Intro::updateScene4() {
if (card_sprites_.at(4)->hasLanded() && texts_.at(7)->hasFinished()) { if (card_sprites_.at(4)->hasLanded() && texts_.at(7)->hasFinished()) {
texts_.at(7)->setEnabled(false); texts_.at(7)->setEnabled(false);
scene_++; scene_++;
shake_done_ = false;
} }
} }
void Intro::updateScene5() { void Intro::updateScene5() {
// Sexta imagen - Globos de café // Sexta imagen - Globos de café
card_sprites_.at(5)->enable();
if (!texts_.at(8)->hasFinished()) { if (!texts_.at(8)->hasFinished()) {
texts_.at(8)->setEnabled(true); texts_.at(8)->setEnabled(true);
} }
@@ -213,6 +216,11 @@ void Intro::update(float delta_time) {
switch (state_) { switch (state_) {
case State::SCENES: case State::SCENES:
// Pausa inicial antes de empezar
if (initial_elapsed_ < INITIAL_DELAY_S) {
initial_elapsed_ += delta_time;
break;
}
updateSprites(delta_time); updateSprites(delta_time);
updateTexts(delta_time); updateTexts(delta_time);
updateScenes(); updateScenes();
@@ -408,6 +416,11 @@ void Intro::initSprites() {
// Límites de pantalla // Límites de pantalla
card->setScreenBounds(param.game.width, param.game.height); card->setScreenBounds(param.game.width, param.game.height);
// Última tarjeta: gana algo de altura al salir (se la lleva el viento)
if (i == TOTAL_SPRITES - 1) {
card->setExitLift(1.2F, 0.15F); // Hasta zoom 1.2, a 0.15/s
}
card_sprites_.push_back(std::move(card)); card_sprites_.push_back(std::move(card));
} }
} }

View File

@@ -38,6 +38,11 @@ class Intro {
static constexpr float TEXT_DISPLAY_DURATION_S = 3.0F; // Duración de visualización de texto static constexpr float TEXT_DISPLAY_DURATION_S = 3.0F; // Duración de visualización de texto
static constexpr float POST_BG_STOP_DELAY_S = 1.0F; // Retraso antes de detener el fondo static constexpr float POST_BG_STOP_DELAY_S = 1.0F; // Retraso antes de detener el fondo
static constexpr float POST_END_DELAY_S = 1.0F; // Retraso antes de finalizar intro static constexpr float POST_END_DELAY_S = 1.0F; // Retraso antes de finalizar intro
static constexpr float INITIAL_DELAY_S = 2.0F; // Pausa antes de empezar las escenas
// --- Constantes de sonido ---
static constexpr const char* SFX_CARD_THROW = "service_menu_select.wav"; // Sonido al lanzar una tarjeta
static constexpr const char* SFX_CARD_IMPACT = "player_collision.wav"; // Sonido al impactar en la mesa
// --- Constantes de layout --- // --- Constantes de layout ---
static constexpr float CARD_BORDER_SIZE = 2.0F; // Tamaño del borde de tarjetas static constexpr float CARD_BORDER_SIZE = 2.0F; // Tamaño del borde de tarjetas
@@ -92,6 +97,8 @@ class Intro {
PostState post_state_ = PostState::STOP_BG; // Estado POST PostState post_state_ = PostState::STOP_BG; // Estado POST
float state_start_time_ = 0.0F; // Tiempo de inicio del estado actual (segundos) float state_start_time_ = 0.0F; // Tiempo de inicio del estado actual (segundos)
Color bg_color_ = param.intro.bg_color; // Color de fondo Color bg_color_ = param.intro.bg_color; // Color de fondo
bool shake_done_ = false; // Evita shake repetido en la misma escena
float initial_elapsed_ = 0.0F; // Tiempo acumulado antes de empezar
// --- Métodos internos --- // --- Métodos internos ---
void update(float delta_time); // Actualiza las variables del objeto void update(float delta_time); // Actualiza las variables del objeto