feat(intro): línies del rètol travessen en direccions oposades
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.
This commit is contained in:
1 parent
af25a31639
commit
00594d9eb2
1 file changed
+17
-11
@@ -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<float>(transition_.elapsed_ms) / static_cast<float>(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<float>(transition_.elapsed_ms) / static_cast<float>(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);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user