animations
This commit is contained in:
+18
-15
@@ -1,9 +1,10 @@
|
||||
//! Board-change wipe animation.
|
||||
//!
|
||||
//! When the player steps through a portal both the old and new boards are rendered
|
||||
//! into off-screen ratatui [`Buffer`]s at init time. Each frame [`TransitionAnimation::update`]
|
||||
//! advances the LFSR-driven reveal bitmap, and the [`Widget`] impl blends the two
|
||||
//! buffers — old cells for unrevealed positions, new cells for revealed ones.
|
||||
//! into off-screen ratatui [`Buffer`]s at init time. Each call to
|
||||
//! [`Animation::update`] advances the LFSR-driven reveal bitmap, and
|
||||
//! [`Animation::draw`] blends the two buffers — old cells for unrevealed positions,
|
||||
//! new cells for revealed ones.
|
||||
|
||||
use kiln_core::Board;
|
||||
use ratatui::{
|
||||
@@ -11,6 +12,8 @@ use ratatui::{
|
||||
layout::Rect,
|
||||
widgets::Widget,
|
||||
};
|
||||
use crate::animation::{Animation, AnimationLayer};
|
||||
use crate::input::InputMode;
|
||||
use crate::render::BoardWidget;
|
||||
|
||||
/// How long the wipe lasts in seconds.
|
||||
@@ -49,9 +52,8 @@ fn lfsr_sequence(total: usize) -> Vec<u32> {
|
||||
/// A board-to-board wipe animation driven by an LFSR.
|
||||
///
|
||||
/// Both boards are rendered into off-screen [`Buffer`]s once at construction.
|
||||
/// Each call to [`update`](TransitionAnimation::update) marks more screen cells
|
||||
/// as "revealed" (using the pre-computed LFSR order); the [`Widget`] impl blends
|
||||
/// old and new buffers cell by cell.
|
||||
/// Implements [`Animation`]: [`update`](Animation::update) marks newly-due cells
|
||||
/// as revealed each frame; [`draw`](Animation::draw) blends old and new buffers.
|
||||
pub struct TransitionAnimation {
|
||||
/// Pre-rendered old board.
|
||||
old_buf: Buffer,
|
||||
@@ -64,13 +66,13 @@ pub struct TransitionAnimation {
|
||||
/// How many entries of `reveal_order` are currently revealed.
|
||||
revealed_count: usize,
|
||||
/// Elapsed seconds since the animation started.
|
||||
pub elapsed: f32,
|
||||
elapsed: f32,
|
||||
}
|
||||
|
||||
impl TransitionAnimation {
|
||||
/// Render both boards into off-screen buffers and build the LFSR sequence.
|
||||
///
|
||||
/// `area` must match the area that will be passed to the widget's `render` call.
|
||||
/// `area` must match the area that will be passed to [`Animation::draw`].
|
||||
pub fn new(old: &Board, new: &Board, area: Rect) -> Self {
|
||||
let total = area.width as usize * area.height as usize;
|
||||
|
||||
@@ -91,11 +93,10 @@ impl TransitionAnimation {
|
||||
elapsed: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Advance the animation by `dt` seconds, marking newly-due cells as revealed.
|
||||
///
|
||||
/// Returns `true` when the animation is complete (all cells revealed).
|
||||
pub fn update(&mut self, dt: f32) -> bool {
|
||||
impl Animation for TransitionAnimation {
|
||||
fn update(&mut self, dt: f32) -> bool {
|
||||
self.elapsed += dt;
|
||||
let total = self.revealed.len();
|
||||
let target =
|
||||
@@ -110,10 +111,8 @@ impl TransitionAnimation {
|
||||
|
||||
self.elapsed >= TRANSITION_DURATION
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for &TransitionAnimation {
|
||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||
fn draw(&self, area: Rect, buf: &mut Buffer) {
|
||||
let w = area.width as usize;
|
||||
for row in 0..area.height {
|
||||
for col in 0..area.width {
|
||||
@@ -131,4 +130,8 @@ impl Widget for &TransitionAnimation {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn layer(&self) -> AnimationLayer { AnimationLayer::Board }
|
||||
|
||||
fn input_mode_after(&self) -> InputMode { InputMode::Board }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user