From 00594d9eb2c7033ca9f6c90dd542685286671860 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sun, 26 Apr 2026 16:59:01 +0200 Subject: [PATCH] =?UTF-8?q?feat(intro):=20l=C3=ADnies=20del=20r=C3=A8tol?= =?UTF-8?q?=20travessen=20en=20direccions=20oposades?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit compute_x guanya un paràmetre from_right que decideix per quin costat entra i per quin surt. La línia de la piràmide es queda amb el patró clàssic (entra per l'esquerra, surt per la dreta); la de la sala s'hi inverteix (entra per la dreta, surt per l'esquerra). El text de l'OUTRO continua amb la direcció original. --- source/game/scenes/game_scene.cpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/source/game/scenes/game_scene.cpp b/source/game/scenes/game_scene.cpp index 45fbc1a..a7f37ef 100644 --- a/source/game/scenes/game_scene.cpp +++ b/source/game/scenes/game_scene.cpp @@ -652,27 +652,30 @@ void GameScene::renderRoomText() { constexpr Uint8 OUTLINE_WHITE = 255; constexpr Uint8 STROKE_DIST = 1; - // Calcula la X animada d'una línia: entra des de l'esquerra - // (off-screen amb el seu cantó dret a x=0), s'atura al CENTER_X - // durant el hold i surt cap a la dreta (off-screen amb el cantó - // esquerre a x=WIDTH). El càlcul depèn de l'amplada de la línia - // — per això la passem com a paràmetre. - auto compute_x = [&](int width, int phase_enter, int phase_exit, int dur_enter, int dur_exit) -> int { + // Calcula la X animada d'una línia: entra des de fora de pantalla, + // s'atura al CENTER_X durant el hold i surt pel costat oposat. + // `from_right=false` és el patró clàssic (entra per l'esquerra, + // surt cap a la dreta); `true` el flipa (entra per la dreta, surt + // cap a l'esquerra). Així les dues línies de l'INTRO poden + // travessar la pantalla en direccions oposades. + auto compute_x = [&](int width, int phase_enter, int phase_exit, int dur_enter, int dur_exit, bool from_right) -> int { const int OFF_LEFT = -width; const int OFF_RIGHT = GameCanvas::WIDTH; + const int OFF_ENTER = from_right ? OFF_RIGHT : OFF_LEFT; + const int OFF_EXIT = from_right ? OFF_LEFT : OFF_RIGHT; if (transition_.phase == phase_enter) { const float T = (dur_enter > 0) ? std::clamp(static_cast(transition_.elapsed_ms) / static_cast(dur_enter), 0.0F, 1.0F) : 1.0F; const auto CURVE = (transition_config_.text_enter_curve != nullptr) ? transition_config_.text_enter_curve : &Easing::linear; - return Easing::lerpInt(OFF_LEFT, GameCanvas::CENTER_X, CURVE(T)); + return Easing::lerpInt(OFF_ENTER, GameCanvas::CENTER_X, CURVE(T)); } if (transition_.phase == phase_exit) { const float T = (dur_exit > 0) ? std::clamp(static_cast(transition_.elapsed_ms) / static_cast(dur_exit), 0.0F, 1.0F) : 1.0F; const auto CURVE = (transition_config_.text_exit_curve != nullptr) ? transition_config_.text_exit_curve : &Easing::linear; - return Easing::lerpInt(GameCanvas::CENTER_X, OFF_RIGHT, CURVE(T)); + return Easing::lerpInt(GameCanvas::CENTER_X, OFF_EXIT, CURVE(T)); } return GameCanvas::CENTER_X; }; @@ -696,8 +699,11 @@ void GameScene::renderRoomText() { const int W_ROOM = room_text_font_->length(LINE_ROOM, KERNING); const int DUR_ENTER = transition_config_.intro_text_enter_ms; const int DUR_EXIT = transition_config_.intro_text_exit_ms; - const int X_PYRAMID = compute_x(W_PYRAMID, 2, 4, DUR_ENTER, DUR_EXIT); - const int X_ROOM = compute_x(W_ROOM, 2, 4, DUR_ENTER, DUR_EXIT); + // Direccions oposades: la línia de la piràmide entra per + // l'esquerra, la de la sala per la dreta. Quan surten, cada + // una continua cap al costat oposat al que ha entrat. + const int X_PYRAMID = compute_x(W_PYRAMID, 2, 4, DUR_ENTER, DUR_EXIT, /*from_right=*/false); + const int X_ROOM = compute_x(W_ROOM, 2, 4, DUR_ENTER, DUR_EXIT, /*from_right=*/true); // Bloc de dues línies centrat al voltant de CENTER_Y. Entre // les dues línies hi posem `intro_text_line_gap_px` extra (a // més del lineHeight natural) per donar-los aire visual; la @@ -712,7 +718,7 @@ void GameScene::renderRoomText() { } else if (state_ == RoomFsm::State::ROOM_OUTRO && transition_.phase >= 0 && transition_.phase <= 2) { const std::string TEXT = Locale::get().text("game.room_complete"); const int W = room_text_font_->length(TEXT, KERNING); - const int X = compute_x(W, 0, 2, transition_config_.outro_text_enter_ms, transition_config_.outro_text_exit_ms); + const int X = compute_x(W, 0, 2, transition_config_.outro_text_enter_ms, transition_config_.outro_text_exit_ms, /*from_right=*/false); const int Y = GameCanvas::CENTER_Y - (room_text_font_->getLineHeight() / 2); draw_line(TEXT, X, Y); }