feat(audio): reverb 'stone_hall' al primer LAND cinemàtic d'INTRO
Lligua el reverb al moment de la cinemàtica d'entrada de sala, no als
salts en general. La sala dóna "més detall" sonor a l'INTRO; un cop el
joc està en marxa, els salts (i els respawns post-mort) tornen al so
sec. Així el primer aterratge es percep com a part de l'animació
d'arribada, no com una propietat permanent del personatge.
- RoomFsm::Config: nou camp `intro_land_reverb_preset` carregat des
de `room_intro.land_reverb` a `data/scenes/game.yaml` (per defecte
'stone_hall'). Buit = sense reverb a l'INTRO.
- Player: membre `next_land_reverb_preset_` consumit per
`integrateJump` al primer aterratge que el trobe armat. Setter
públic `armNextLandReverb(preset)` per a GameScene. Cap altre punt
(respawn, exit, disable) el toca: el reverb és estrictament
one-shot lligat al spawn aeri d'INTRO.
- GameScene::triggerPlayerSpawn: arma el preset al jugador just
després de `spawnFromAir`, així cada slot rep el seu reverb un
sol cop per cinemàtica.
- JumpConfig perd `land_reverb_preset` i els YAMLs de Sam/Morcus
perden `land_reverb`: la decisió ja no viu al personatge.
This commit is contained in:
1 parent
d3698a1504
commit
47bb92144e
6 files changed
+45
No files matched your search
@@ -13,6 +13,11 @@ room_intro:
|
|||||||
line_gap_px: -4 # px extra entre les dues línies (piràmide / sala)
|
line_gap_px: -4 # px extra entre les dues línies (piràmide / sala)
|
||||||
player_spawn_delay_ms: 2400 # ms des de l'inici d'INTRO al spawn aeri.
|
player_spawn_delay_ms: 2400 # ms des de l'inici d'INTRO al spawn aeri.
|
||||||
player2_spawn_delay_ms: 2700 # només mode BOTH. Trenca la simultaneïtat.
|
player2_spawn_delay_ms: 2700 # només mode BOTH. Trenca la simultaneïtat.
|
||||||
|
# Preset de reverb (catàleg a `data/sounds.yaml`) aplicat al primer
|
||||||
|
# LAND de cada jugador durant la cinemàtica d'entrada. La sala dona
|
||||||
|
# "més detall" sonor a l'INTRO; els salts del joc i els respawns
|
||||||
|
# post-mort cauen al so sec. Buit o absent = sense reverb.
|
||||||
|
land_reverb: stone_hall
|
||||||
|
|
||||||
room_outro:
|
room_outro:
|
||||||
text_enter_ms: 400
|
text_enter_ms: 400
|
||||||
|
|||||||
@@ -697,7 +697,15 @@ auto Player::integrateJump(float delta_time) -> bool {
|
|||||||
state_ = State::LANDING_STUN;
|
state_ = State::LANDING_STUN;
|
||||||
landing_stun_remaining_ms_ = static_cast<float>(jump_config.landing_stun_ms);
|
landing_stun_remaining_ms_ = static_cast<float>(jump_config.landing_stun_ms);
|
||||||
if (!jump_config.land_sound_key.empty() && Audio::get() != nullptr) {
|
if (!jump_config.land_sound_key.empty() && Audio::get() != nullptr) {
|
||||||
|
// Consumeix el preset armat per GameScene al spawn aeri
|
||||||
|
// d'INTRO (single-shot): el primer LAND el sona reverberat,
|
||||||
|
// els salts següents cauen al camí sec.
|
||||||
|
if (next_land_reverb_preset_.empty()) {
|
||||||
Audio::get()->playSound(jump_config.land_sound_key, Audio::Group::GAME);
|
Audio::get()->playSound(jump_config.land_sound_key, Audio::Group::GAME);
|
||||||
|
} else {
|
||||||
|
Audio::get()->playSoundWithReverb(jump_config.land_sound_key, next_land_reverb_preset_, Audio::Group::GAME);
|
||||||
|
next_land_reverb_preset_.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (bus_ != nullptr) {
|
if (bus_ != nullptr) {
|
||||||
bus_->publish(Event{
|
bus_->publish(Event{
|
||||||
|
|||||||
@@ -259,6 +259,15 @@ class Player : public AnimatedSprite {
|
|||||||
// al respawn post-mort: mateixa entrada cinemàtica.
|
// al respawn post-mort: mateixa entrada cinemàtica.
|
||||||
void spawnFromAir(float x, float y);
|
void spawnFromAir(float x, float y);
|
||||||
|
|
||||||
|
// Arma un preset de reverb (catàleg a `data/sounds.yaml`) per al
|
||||||
|
// pròxim aterratge d'aquest jugador. Pensat per a la cinemàtica
|
||||||
|
// d'INTRO de sala: GameScene crida aquesta funció just després de
|
||||||
|
// `spawnFromAir`, i el primer LAND consumeix el preset (queda buit
|
||||||
|
// immediatament). Els salts posteriors del joc, els respawns
|
||||||
|
// post-mort i el reset general no rearmen res. `preset` buit
|
||||||
|
// desactiva el reverb del proper LAND (no afecta cap LAND posterior).
|
||||||
|
void armNextLandReverb(std::string preset) { next_land_reverb_preset_ = std::move(preset); }
|
||||||
|
|
||||||
// Alçada actual del salt (píxels visuals per damunt del sòl).
|
// Alçada actual del salt (píxels visuals per damunt del sòl).
|
||||||
// 0 quan està a terra. L'usa el render i el sistema de col·lisions
|
// 0 quan està a terra. L'usa el render i el sistema de col·lisions
|
||||||
// per altura.
|
// per altura.
|
||||||
@@ -390,6 +399,14 @@ class Player : public AnimatedSprite {
|
|||||||
// gestiona `intended_vx_/vy_` escalats pel resolver.
|
// gestiona `intended_vx_/vy_` escalats pel resolver.
|
||||||
bool being_pushed_{false};
|
bool being_pushed_{false};
|
||||||
|
|
||||||
|
// Preset de reverb (catàleg de `data/sounds.yaml`) que el pròxim
|
||||||
|
// LAND ha de fer servir; buit = so sec. L'arma `armNextLandReverb`
|
||||||
|
// (cridada per GameScene al spawn aeri d'INTRO) i el consumeix
|
||||||
|
// `integrateJump` quan el jugador toca terra. Cap altre punt
|
||||||
|
// (respawn, exit, disable) el toca: així només sona reverberat el
|
||||||
|
// primer LAND de la cinemàtica d'entrada.
|
||||||
|
std::string next_land_reverb_preset_;
|
||||||
|
|
||||||
// Escala d'empenta usada per `snapToLane` quan descobreix un blocker
|
// Escala d'empenta usada per `snapToLane` quan descobreix un blocker
|
||||||
// (mateixa del resolver). 1.0 = sense escalar (comportament si
|
// (mateixa del resolver). 1.0 = sense escalar (comportament si
|
||||||
// GameScene no ha cridat setPushFactor).
|
// GameScene no ha cridat setPushFactor).
|
||||||
|
|||||||
@@ -556,6 +556,11 @@ void GameScene::triggerPlayerSpawn(std::size_t slot_index) {
|
|||||||
float x = SINGLE_X;
|
float x = SINGLE_X;
|
||||||
if (BOTH_ACTIVE) { x = (slot_index == 0) ? SPAWN.p1_x : SPAWN.p2_x; }
|
if (BOTH_ACTIVE) { x = (slot_index == 0) ? SPAWN.p1_x : SPAWN.p2_x; }
|
||||||
players_[slot_index]->spawnFromAir(x, SPAWN.y);
|
players_[slot_index]->spawnFromAir(x, SPAWN.y);
|
||||||
|
// Arma el reverb del primer LAND com a part de la cinemàtica
|
||||||
|
// d'INTRO. Una sola vegada per spawn aeri: el respawn post-mort
|
||||||
|
// (que no passa per ací) cau al camí sec. Si el preset està buit
|
||||||
|
// al YAML, l'arma queda buida i el LAND és sec igualment.
|
||||||
|
players_[slot_index]->armNextLandReverb(transition_config_.intro_land_reverb_preset);
|
||||||
|
|
||||||
std::cout << "[ROOM] spawn cinematic P" << (slot_index + 1) << ": airborne entry\n";
|
std::cout << "[ROOM] spawn cinematic P" << (slot_index + 1) << ": airborne entry\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ namespace RoomFsm {
|
|||||||
// El YAML pot trencar la simultaneïtat fixant un valor propi.
|
// El YAML pot trencar la simultaneïtat fixant un valor propi.
|
||||||
cfg.player2_spawn_delay_ms = readChildInt(n, "player2_spawn_delay_ms", cfg.player_spawn_delay_ms);
|
cfg.player2_spawn_delay_ms = readChildInt(n, "player2_spawn_delay_ms", cfg.player_spawn_delay_ms);
|
||||||
cfg.intro_text_line_gap_px = readChildInt(n, "line_gap_px", cfg.intro_text_line_gap_px);
|
cfg.intro_text_line_gap_px = readChildInt(n, "line_gap_px", cfg.intro_text_line_gap_px);
|
||||||
|
if (n.contains("land_reverb")) {
|
||||||
|
cfg.intro_land_reverb_preset = n["land_reverb"].get_value<std::string>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (yaml.contains("room_outro")) {
|
if (yaml.contains("room_outro")) {
|
||||||
const auto& n = yaml["room_outro"];
|
const auto& n = yaml["room_outro"];
|
||||||
|
|||||||
@@ -80,6 +80,13 @@ namespace RoomFsm {
|
|||||||
UiConfig::CurveFn text_enter_curve{nullptr};
|
UiConfig::CurveFn text_enter_curve{nullptr};
|
||||||
UiConfig::CurveFn text_exit_curve{nullptr};
|
UiConfig::CurveFn text_exit_curve{nullptr};
|
||||||
|
|
||||||
|
// Preset de reverb (catàleg a `data/sounds.yaml`) que GameScene
|
||||||
|
// arma al jugador al spawn aeri d'INTRO. Es consumeix al primer
|
||||||
|
// aterratge cinemàtic; els salts posteriors del joc i els
|
||||||
|
// respawns post-mort cauen al so sec. Buit = sense reverb (la
|
||||||
|
// cinemàtica d'entrada sona igual que un salt qualsevol).
|
||||||
|
std::string intro_land_reverb_preset;
|
||||||
|
|
||||||
// Panel translúcid sota el rètol de transició (INTRO i OUTRO).
|
// Panel translúcid sota el rètol de transició (INTRO i OUTRO).
|
||||||
// Centrat verticalment al centre del playfield, ocupa tota
|
// Centrat verticalment al centre del playfield, ocupa tota
|
||||||
// l'amplada del canvas. Creix d'altura 0 → height_px durant la
|
// l'amplada del canvas. Creix d'altura 0 → height_px durant la
|
||||||
|
|||||||
Reference in new issue
Block a user