feat(outro): pausa en negre opac entre sales (5a fase de OUTRO)
Nova fase 4 a ROOM_OUTRO: black_hold. Va just després del fade_out; durant aquesta fase la pantalla queda completament en negre opac i la FSM espera abans de transitar a INTRO. Permet donar respir entre el final del rètol Fase/Completada i el rellançament del Piramide/Sala de la sala següent, sense necessitat d'un estat nou. Implementacio: - RoomFsm::Config guanya outro_black_hold_ms (default 0 — backward compatible). YAML key room_outro.black_hold_ms al data/scenes/game.yaml (default visible 500 ms; lo afines sense recompilar). - L'array DURS de l'OUTRO passa de 4 a 5 elements; el while-loop consumeix la fase exactament igual. - renderRoomFade detecta fase 4 i dibuixa alpha=255 fix; sense aquesta branca, el fade s'apagaria a final de la fase 3 i el món tornaria a ser visible durant la pausa. - renderRoomText no canvia: phases 3 i 4 ja queden fora del rang 0..2 on dibuixa el rètol. Backward compat: black_hold_ms=0 fa que el while-loop avance immediatament la fase i recauen tots els tests existents (T7 i companys) sense modificacions.
This commit is contained in:
1 parent
7982df922b
commit
98303f7ce8
4 files changed
+25
-5
No files matched your search
@@ -18,6 +18,7 @@ room_outro:
|
||||
text_exit_ms: 400
|
||||
fade_out_ms: 500 # món visible → negre opac
|
||||
line_gap_px: 0 # px extra entre les dues línies (fase / completada)
|
||||
black_hold_ms: 500 # pausa en negre abans d'entrar a la pròxima sala
|
||||
|
||||
text:
|
||||
# Noms d'easing tal com els resol UiConfig::curveByName (vegeu
|
||||
|
||||
@@ -609,9 +609,16 @@ void GameScene::updateRoomTransition(int delta_ms) {
|
||||
|
||||
void GameScene::renderRoomFade() {
|
||||
// Fade negre sobre el món, pintat un cop els actors ja estan al
|
||||
// canvas i abans del HUD. Dos casos:
|
||||
// canvas i abans del HUD. Tres casos:
|
||||
// ROOM_INTRO/fase 0: 255 → 0 (entrada de sala, món emergent)
|
||||
// ROOM_OUTRO/fase 3: 0 → 255 (sortida de sala, món s'apaga)
|
||||
// ROOM_OUTRO/fase 4: alpha=255 fix (pausa en negre opac abans del
|
||||
// rellançament de la pròxima sala)
|
||||
if (state_ == RoomFsm::State::ROOM_OUTRO && transition_.phase == 4) {
|
||||
Screen::get().blendRect(0, 0, GameCanvas::WIDTH, GameCanvas::HEIGHT, 0x00000000U, 255);
|
||||
return;
|
||||
}
|
||||
|
||||
int dur = 0;
|
||||
float t = 0.0F;
|
||||
bool fade_in = false;
|
||||
@@ -644,8 +651,10 @@ void GameScene::renderRoomText() {
|
||||
// (piràmide damunt, sala davall) que comparteixen
|
||||
// animació però es dibuixen amb writeDX independents
|
||||
// per deixar la porta oberta a desacoblar-les.
|
||||
// ROOM_OUTRO: phases 0..2 → enter / hold / exit; una línia
|
||||
// ("fase completada").
|
||||
// ROOM_OUTRO: phases 0..2 → enter / hold / exit; dues línies
|
||||
// oposades ("fase" / "completada"). Phase 3 és el
|
||||
// fade-out i 4 la pausa en negre — cap text en cap
|
||||
// de les dues.
|
||||
if (!room_text_font_) { return; }
|
||||
|
||||
constexpr int KERNING = 0;
|
||||
|
||||
@@ -52,6 +52,7 @@ namespace RoomFsm {
|
||||
cfg.outro_text_exit_ms = readChildInt(n, "text_exit_ms", cfg.outro_text_exit_ms);
|
||||
cfg.outro_fade_out_ms = readChildInt(n, "fade_out_ms", cfg.outro_fade_out_ms);
|
||||
cfg.outro_text_line_gap_px = readChildInt(n, "line_gap_px", cfg.outro_text_line_gap_px);
|
||||
cfg.outro_black_hold_ms = readChildInt(n, "black_hold_ms", cfg.outro_black_hold_ms);
|
||||
}
|
||||
if (yaml.contains("text")) {
|
||||
const auto& n = yaml["text"];
|
||||
@@ -91,11 +92,15 @@ namespace RoomFsm {
|
||||
}
|
||||
|
||||
// ROOM_OUTRO
|
||||
const std::array<int, 4> DURS = {
|
||||
const std::array<int, 5> DURS = {
|
||||
cfg.outro_text_enter_ms,
|
||||
cfg.outro_text_hold_ms,
|
||||
cfg.outro_text_exit_ms,
|
||||
cfg.outro_fade_out_ms,
|
||||
// Pausa final en negre, després del fade-out i abans del
|
||||
// canvi a INTRO. Si és 0 ms, el while-loop la consumeix
|
||||
// sense esperar — comportament idèntic a l'històric.
|
||||
cfg.outro_black_hold_ms,
|
||||
};
|
||||
while (t.phase < static_cast<int>(DURS.size()) && t.elapsed_ms >= DURS[t.phase]) {
|
||||
t.elapsed_ms -= DURS[t.phase];
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace RoomFsm {
|
||||
// Sub-fase i temps acumulat dins de l'estat actual. Es reseteja a
|
||||
// {0, 0} quan es canvia d'estat. Significat de `phase` per estat:
|
||||
// ROOM_INTRO: 0=fade_in, 1=text_delay, 2=text_enter, 3=text_hold, 4=text_exit
|
||||
// ROOM_OUTRO: 0=text_enter, 1=text_hold, 2=text_exit, 3=fade_out
|
||||
// ROOM_OUTRO: 0=text_enter, 1=text_hold, 2=text_exit, 3=fade_out, 4=black_hold
|
||||
// PLAYING: no s'usa.
|
||||
struct Transition {
|
||||
int phase{0};
|
||||
@@ -41,6 +41,11 @@ namespace RoomFsm {
|
||||
int outro_text_hold_ms{1000};
|
||||
int outro_text_exit_ms{500};
|
||||
int outro_fade_out_ms{500};
|
||||
// Pausa en negre opac entre el final de l'OUTRO i el començament
|
||||
// de l'INTRO de la sala següent. 0 = sense pausa (transició
|
||||
// immediata, comportament històric). El YAML pot sobreescriure
|
||||
// sense recompilar — útil per donar respir abans del nou rètol.
|
||||
int outro_black_hold_ms{0};
|
||||
|
||||
// Mil·lisegons des de l'inici de ROOM_INTRO en què cau la
|
||||
// cinemàtica d'spawn aeri dels jugadors actius. Independent del
|
||||
|
||||
Reference in new issue
Block a user