diff --git a/source/game/effects/debris_manager.cpp b/source/game/effects/debris_manager.cpp index 4cdb8e3..b727d1d 100644 --- a/source/game/effects/debris_manager.cpp +++ b/source/game/effects/debris_manager.cpp @@ -64,8 +64,11 @@ namespace Effects { return; } - // Reproducir sonido de explosión - Audio::get()->playSound(sound, Audio::Group::GAME); + // Reproducir sonido de explosión. Cadena buida = explosió silenciosa + // (p. ex. el logo dins el cicle d'atracció). + if (!sound.empty()) { + Audio::get()->playSound(sound, Audio::Group::GAME); + } // Notificar als subscriptors (border, playfield, etc.). if (explosion_callback_) { diff --git a/source/game/effects/debris_manager.hpp b/source/game/effects/debris_manager.hpp index ec56584..3f5ca08 100644 --- a/source/game/effects/debris_manager.hpp +++ b/source/game/effects/debris_manager.hpp @@ -64,6 +64,7 @@ namespace Effects { const Vec2& velocitat_objecte = {.x = 0.0F, .y = 0.0F}, float velocitat_angular = 0.0F, float factor_herencia_visual = 0.0F, + // sound: nom del so d'explosió. Cadena buida ("") = explosió silenciosa. const std::string& sound = Defaults::Sound::ENEMY_EXPLOSION, SDL_Color color = {0, 0, 0, 0}, // alpha==0 → fragmentos usan oscilador global float lifetime = Defaults::Physics::Debris::TEMPS_VIDA, diff --git a/source/game/scenes/logo_scene.cpp b/source/game/scenes/logo_scene.cpp index 55640ab..68bbf07 100644 --- a/source/game/scenes/logo_scene.cpp +++ b/source/game/scenes/logo_scene.cpp @@ -202,14 +202,18 @@ void LogoScene::updateExplosions(float delta_time) { const auto& letter = letters_[index_actual]; debris_manager_->explode( - letter.shape, // Forma a explode - letter.position, // Posición - 0.0F, // Angle (sin rotación) - FINAL_SCALE, // Escala (lletres a scale final) - SPEED_EXPLOSIO, // Velocidad base - 1.0F, // Brightness màxim (per defecte) - {.x = 0.0F, .y = 0.0F} // Sin velocity (per defecte) - ); + letter.shape, // Forma a explode + letter.position, // Posición + 0.0F, // Angle (sin rotación) + FINAL_SCALE, // Escala (lletres a scale final) + SPEED_EXPLOSIO, // Velocidad base + 1.0F, // Brightness màxim (per defecte) + {.x = 0.0F, .y = 0.0F}, // Sin velocity (per defecte) + 0.0F, // Velocitat angular (per defecte) + 0.0F, // Factor herència visual (per defecte) + // Dins el cicle d'atracció les explosions són mudes; fora, so + // d'explosió per defecte. + attract_silent_ ? "" : Defaults::Sound::ENEMY_EXPLOSION); std::cout << "[LogoScene] Explota letter " << letter_explosion_index_ << "\n"; diff --git a/source/game/scenes/title_scene.cpp b/source/game/scenes/title_scene.cpp index 25e292f..c930a24 100644 --- a/source/game/scenes/title_scene.cpp +++ b/source/game/scenes/title_scene.cpp @@ -489,11 +489,16 @@ void TitleScene::updateBlackScreenState(float delta_time) { } } -void TitleScene::updateDemoDiveState(float delta_time) { +void TitleScene::advanceDive(float delta_time) { namespace D = Defaults::Game::Dive; dive_time_ += delta_time; - const float T = std::min(dive_time_ / D::DURATION, 1.0F); - const float EASED = Easing::easeInQuad(T); // acceleració cap al punt de fuga + // T SENSE topall: easeInQuad (=T²) fa que la posició creixi quadràticament, + // és a dir, la velocitat creix linealment → acceleració constant que no + // s'atura. CAMERA_DISTANCE i ZOOM_MAX deixen de ser límits: són el valor + // assolit en l'instant de referència (T=1, quan cau la cortinilla) i a + // partir d'ací el moviment continua accelerant (std::lerp extrapola). + const float T = dive_time_ / D::DURATION; + const float EASED = Easing::easeInQuad(T); // Càmera 3D real cap a +Z: starfield i naus es projecten amb la càmera, així // que les estrelles es rasguen i les naus creixen i s'escapen pels costats. @@ -507,14 +512,21 @@ void TitleScene::updateDemoDiveState(float delta_time) { } // Logo i peu són 2D: els fakegem el dive amb un zoom des del centre. dive_zoom_ = std::lerp(1.0F, D::ZOOM_MAX, EASED); +} - if (T >= 1.0F) { +void TitleScene::updateDemoDiveState(float delta_time) { + advanceDive(delta_time); + + // En l'instant de referència (dive_time_ == DURATION) cau la cortinilla, + // però la càmera NO s'atura: segueix accelerant a DEMO_CURTAIN. + if (dive_time_ >= Defaults::Game::Dive::DURATION) { current_state_ = TitleState::DEMO_CURTAIN; curtain_.cover(Defaults::Game::Curtain::COVER_DURATION); } } void TitleScene::updateDemoCurtainState(float delta_time) { + advanceDive(delta_time); // la càmera continua accelerant sota la tela curtain_.update(delta_time); if (curtain_.isDone()) { context_.setNextScene(SceneType::GAME); diff --git a/source/game/scenes/title_scene.hpp b/source/game/scenes/title_scene.hpp index 28f9c74..f2af90d 100644 --- a/source/game/scenes/title_scene.hpp +++ b/source/game/scenes/title_scene.hpp @@ -154,6 +154,11 @@ class TitleScene final : public Scene { void updateBlackScreenState(float delta_time); void updateDemoDiveState(float delta_time); void updateDemoCurtainState(float delta_time); + // Integra el dive (attract): avança la càmera cap a +Z i puja el zoom dels + // elements 2D amb acceleració (easeInQuad), sense topall. Es crida tant a + // DEMO_DIVE com a DEMO_CURTAIN perquè la càmera no pare mai un cop comença: + // segueix accelerant fins i tot sota la cortinilla, fins al salt a la demo. + void advanceDive(float delta_time); void handleSkipInput(); void handleStartInput(); void triggerExitForJoinedPlayers(bool p1_was_active, bool p2_was_active, const char* log_prefix);