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 OUTLINE_WHITE = 255;
|
||||||
constexpr Uint8 STROKE_DIST = 1;
|
constexpr Uint8 STROKE_DIST = 1;
|
||||||
|
|
||||||
// Calcula la X animada d'una línia: entra des de l'esquerra
|
// Calcula la X animada d'una línia: entra des de fora de pantalla,
|
||||||
// (off-screen amb el seu cantó dret a x=0), s'atura al CENTER_X
|
// s'atura al CENTER_X durant el hold i surt pel costat oposat.
|
||||||
// durant el hold i surt cap a la dreta (off-screen amb el cantó
|
// `from_right=false` és el patró clàssic (entra per l'esquerra,
|
||||||
// esquerre a x=WIDTH). El càlcul depèn de l'amplada de la línia
|
// surt cap a la dreta); `true` el flipa (entra per la dreta, surt
|
||||||
// — per això la passem com a paràmetre.
|
// cap a l'esquerra). Així les dues línies de l'INTRO poden
|
||||||
auto compute_x = [&](int width, int phase_enter, int phase_exit, int dur_enter, int dur_exit) -> int {
|
// 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_LEFT = -width;
|
||||||
const int OFF_RIGHT = GameCanvas::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) {
|
if (transition_.phase == phase_enter) {
|
||||||
const float T = (dur_enter > 0)
|
const float T = (dur_enter > 0)
|
||||||
? std::clamp(static_cast<float>(transition_.elapsed_ms) / static_cast<float>(dur_enter), 0.0F, 1.0F)
|
? std::clamp(static_cast<float>(transition_.elapsed_ms) / static_cast<float>(dur_enter), 0.0F, 1.0F)
|
||||||
: 1.0F;
|
: 1.0F;
|
||||||
const auto CURVE = (transition_config_.text_enter_curve != nullptr) ? transition_config_.text_enter_curve : &Easing::linear;
|
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) {
|
if (transition_.phase == phase_exit) {
|
||||||
const float T = (dur_exit > 0)
|
const float T = (dur_exit > 0)
|
||||||
? std::clamp(static_cast<float>(transition_.elapsed_ms) / static_cast<float>(dur_exit), 0.0F, 1.0F)
|
? std::clamp(static_cast<float>(transition_.elapsed_ms) / static_cast<float>(dur_exit), 0.0F, 1.0F)
|
||||||
: 1.0F;
|
: 1.0F;
|
||||||
const auto CURVE = (transition_config_.text_exit_curve != nullptr) ? transition_config_.text_exit_curve : &Easing::linear;
|
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;
|
return GameCanvas::CENTER_X;
|
||||||
};
|
};
|
||||||
@@ -696,8 +699,11 @@ void GameScene::renderRoomText() {
|
|||||||
const int W_ROOM = room_text_font_->length(LINE_ROOM, KERNING);
|
const int W_ROOM = room_text_font_->length(LINE_ROOM, KERNING);
|
||||||
const int DUR_ENTER = transition_config_.intro_text_enter_ms;
|
const int DUR_ENTER = transition_config_.intro_text_enter_ms;
|
||||||
const int DUR_EXIT = transition_config_.intro_text_exit_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);
|
// Direccions oposades: la línia de la piràmide entra per
|
||||||
const int X_ROOM = compute_x(W_ROOM, 2, 4, DUR_ENTER, DUR_EXIT);
|
// 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
|
// 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
|
// les dues línies hi posem `intro_text_line_gap_px` extra (a
|
||||||
// més del lineHeight natural) per donar-los aire visual; la
|
// 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) {
|
} else if (state_ == RoomFsm::State::ROOM_OUTRO && transition_.phase >= 0 && transition_.phase <= 2) {
|
||||||
const std::string TEXT = Locale::get().text("game.room_complete");
|
const std::string TEXT = Locale::get().text("game.room_complete");
|
||||||
const int W = room_text_font_->length(TEXT, KERNING);
|
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);
|
const int Y = GameCanvas::CENTER_Y - (room_text_font_->getLineHeight() / 2);
|
||||||
draw_line(TEXT, X, Y);
|
draw_line(TEXT, X, Y);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user