transition

This commit is contained in:
2026-06-13 18:43:29 -05:00
parent 6818f0545a
commit 299570bec8
6 changed files with 254 additions and 20 deletions
+39 -5
View File
@@ -1,15 +1,30 @@
use std::cell::RefCell;
use std::rc::Rc;
use std::time::Duration;
use kiln_core::Board;
use kiln_core::game::GameState;
use crate::log::LogState;
use crate::scroll_overlay::{ScrollAnimState, ScrollOverlayState};
use crate::transition::TransitionAnimation;
/// View-only UI state for the log panel and scroll overlay. This is presentation
/// state, so it lives in the front-end rather than on the engine's [`GameState`].
/// A pair of board `Rc`s (old board, new board) queued for transition pre-rendering.
type PendingTransition = Option<(Rc<RefCell<Board>>, Rc<RefCell<Board>>)>;
/// View-only UI state for the log panel, scroll overlay, and board transitions.
/// Presentation-only state; lives in the front-end, not on [`GameState`].
pub(crate) struct Ui {
/// State for the log panel (open/closed, height, scroll position).
pub(crate) log: LogState,
/// Scroll position, bounds, and animation state for an active scroll overlay.
pub(crate) overlay: ScrollOverlayState,
/// Old and new board Rcs waiting to be pre-rendered on the next `draw()` call.
/// Populated when a portal transition is detected; consumed in `draw()`.
pub(crate) pending_transition: PendingTransition,
/// Active board-wipe animation. While `Some`, ticks and input are suppressed.
pub(crate) transition: Option<TransitionAnimation>,
/// Set when the wipe completes; puts the game in [`InputMode::Frozen`] until the
/// player presses any key.
pub(crate) post_transition_wait: bool,
}
impl Default for Ui {
@@ -17,6 +32,9 @@ impl Default for Ui {
Self {
log: LogState::new(),
overlay: ScrollOverlayState::default(),
pending_transition: None,
transition: None,
post_transition_wait: false,
}
}
}
@@ -30,10 +48,26 @@ impl Ui {
/// Advances all time-driven UI state by `dt` and drives the game tick.
///
/// Advances the scroll overlay animation, dispatches any finished close
/// animation, ticks the game when no overlay is blocking, and starts the
/// open animation when a new scroll appears.
/// Board-wipe transition and post-transition freeze take priority: while either
/// is active the game does not tick and no scroll overlay is processed. Once the
/// wipe completes, `post_transition_wait` is set so input stays frozen until the
/// player presses any key. Normal scroll-overlay handling resumes after that.
pub(crate) fn tick(&mut self, dt: Duration, game: &mut GameState) {
// Advance the wipe animation; transition to frozen state when done.
if let Some(ref mut tr) = self.transition {
if tr.update(dt.as_secs_f32()) {
self.transition = None;
self.post_transition_wait = true;
}
return; // no game tick during the wipe
}
// Game stays frozen until the player presses any key.
if self.post_transition_wait {
return;
}
// Normal path: advance the scroll overlay and tick the game.
self.overlay.advance_anim(dt.as_secs_f32());
if self.overlay.close_finished() {
game.close_scroll(self.overlay.take_choice().as_deref());