From 7867100ea1bc26950b3d0b1c035baf37e7856cac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= <fandabohacek@gmail.com> Date: Tue, 20 Dec 2022 19:53:46 +0100 Subject: [PATCH] feat: add guess and number increment animations --- src/animation.rs | 94 ++++++++++++++++++++++++++++++++++++++++++++--- src/entrypoint.rs | 36 ++++++++++++++++-- 2 files changed, 121 insertions(+), 9 deletions(-) diff --git a/src/animation.rs b/src/animation.rs index 7d2db4e..026e743 100644 --- a/src/animation.rs +++ b/src/animation.rs @@ -1,6 +1,16 @@ use super::filled_seven_segment; use super::led_matrix; +const WIN_ANIMATION_MAX_LED_OUTER_STEP: u8 = 5; // max led_step +const WIN_ANIMATION_MAX_LED_STEP: u8 = 4; // add led_step +const WIN_ANIMATION_MAX_LED_INNER_STEP: u16 = 2500; // 10000; // add led_quarter + +const HELO_ANIMATION_MAX_INNER_STEP: u16 = 5000; // 20000; +const HELO_ANIMATION_MAX_OUTER_STEP: u16 = 5; + +const GUESS_ANIMATION_MAX_STEP: u16 = 3000; +const DIGIT_INCREMENT_ANIMATION_MAX_STEP: u16 = 1000; + #[derive(PartialEq, Eq)] pub enum AnimationState { Running, @@ -27,12 +37,86 @@ pub struct WinAnimation { pub hidden: bool } -const WIN_ANIMATION_MAX_LED_OUTER_STEP: u8 = 5; // max led_step -const WIN_ANIMATION_MAX_LED_STEP: u8 = 4; // add led_step -const WIN_ANIMATION_MAX_LED_INNER_STEP: u16 = 2500; // 10000; // add led_quarter +pub struct GuessAnimation { + pub step: u16 +} -const HELO_ANIMATION_MAX_INNER_STEP: u16 = 5000; // 20000; -const HELO_ANIMATION_MAX_OUTER_STEP: u16 = 5; +pub struct DigitIncrementAnimation { + pub digit_index: usize, + pub step: u16 +} + +impl DigitIncrementAnimation { + pub fn create(digit_index: usize) -> DigitIncrementAnimation { + DigitIncrementAnimation { + step: 0, + digit_index + } + } + + pub fn reset(&mut self, digit_index: usize) { + self.digit_index = digit_index; + self.step = 0; + } +} + +impl Animation for DigitIncrementAnimation { + fn step(&mut self, seven_segment: &mut filled_seven_segment::FilledSevenSegment, _: &mut led_matrix::LEDMatrix) -> AnimationState { + if !self.running() { + return AnimationState::End; + } + + if self.step == 0 { + seven_segment.hide_digit(self.digit_index); + } + self.step += 1; + + AnimationState::Running + } + + fn cleanup(&mut self, seven_segment: &mut filled_seven_segment::FilledSevenSegment, _: &mut led_matrix::LEDMatrix) { + seven_segment.show_digit(self.digit_index); + } + + fn running(&self) -> bool { + self.step < DIGIT_INCREMENT_ANIMATION_MAX_STEP + } +} + +impl GuessAnimation { + pub fn create() -> GuessAnimation { + GuessAnimation { + step: 0 + } + } + + pub fn reset(&mut self) { + self.step = 0; + } +} + +impl Animation for GuessAnimation { + fn step(&mut self, seven_segment: &mut filled_seven_segment::FilledSevenSegment, _: &mut led_matrix::LEDMatrix) -> AnimationState { + if !self.running() { + return AnimationState::End; + } + + if self.step == 0 { + seven_segment.hide_all_digits(); + } + self.step += 1; + + AnimationState::Running + } + + fn cleanup(&mut self, seven_segment: &mut filled_seven_segment::FilledSevenSegment, _: &mut led_matrix::LEDMatrix) { + seven_segment.show_all_digits(); + } + + fn running(&self) -> bool { + self.step < GUESS_ANIMATION_MAX_STEP + } +} impl WinAnimation { pub fn create(number: u16) -> WinAnimation { diff --git a/src/entrypoint.rs b/src/entrypoint.rs index 70620ba..5d05633 100644 --- a/src/entrypoint.rs +++ b/src/entrypoint.rs @@ -29,6 +29,15 @@ static mut WIN_ANIMATION: animation::WinAnimation = animation::WinAnimation { hidden: true, }; +static mut GUESS_ANIMATION: animation::GuessAnimation = animation::GuessAnimation { + step: 0, +}; + +static mut DIGIT_INC_ANIMATION: animation::DigitIncrementAnimation = animation::DigitIncrementAnimation { + step: 0, + digit_index: 0, +}; + #[atmega_hal::entry] fn main() -> ! { // PERIPHERALS @@ -88,7 +97,9 @@ fn main() -> ! { unsafe { HELLO_ANIMATION = animation::HelloAnimation::create(); WIN_ANIMATION = animation::WinAnimation::create(0); - game.animation = Some(&mut HELLO_ANIMATION); + GUESS_ANIMATION = animation::GuessAnimation::create(); + DIGIT_INC_ANIMATION = animation::DigitIncrementAnimation::create(0); + game.set_animation(&mut HELLO_ANIMATION); } let mut step: u64 = 0; @@ -159,6 +170,10 @@ impl Game { } self.update_led_matrix(); + unsafe { + self.set_animation(&mut GUESS_ANIMATION); + GUESS_ANIMATION.reset(); + } } let mut btns_pressed: [bool; DIGITS] = [false; DIGITS]; @@ -169,13 +184,26 @@ impl Game { for (i, pressed) in btns_pressed.iter().enumerate() { if *pressed { - self.increase_digit(DIGITS - 1 - i); + let digit_index = DIGITS - 1 - i; + self.increase_digit(digit_index); + unsafe { + self.set_animation(&mut DIGIT_INC_ANIMATION); + DIGIT_INC_ANIMATION.reset(digit_index); + } } } } } } + pub fn set_animation(&mut self, animation: &'static mut dyn animation::Animation) { + if let Some(current_animation) = &mut self.animation { + current_animation.cleanup(&mut self.seven_segment, &mut self.led_matrix); + } + + self.animation = Some(animation); + } + fn get_digit(number: u16, digit_index: usize) -> u8 { let mut digit = number; for _ in 0..digit_index { @@ -205,7 +233,7 @@ impl Game { for j in 0..DIGITS { if i != j && - current_digits[j] != guessing_digits[i] && + current_digits[j] != guessing_digits[j] && current_digits[i] == guessing_digits[j] { self.led_matrix.set( @@ -238,8 +266,8 @@ impl Game { fn end_current_game(&mut self) { unsafe { + self.set_animation(&mut WIN_ANIMATION); WIN_ANIMATION.reset(self.guessing_number.unwrap()); - self.animation = Some(&mut WIN_ANIMATION); } self.cleanup_current_game(); self.state = GameState::Won; -- 2.48.1