~ruther/avr-guess-the-number

7867100ea1bc26950b3d0b1c035baf37e7856cac — František Boháček 2 years ago 6ed7b9d
feat: add guess and number increment animations
2 files changed, 121 insertions(+), 9 deletions(-)

M src/animation.rs
M src/entrypoint.rs
M src/animation.rs => src/animation.rs +89 -5
@@ 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 {

M src/entrypoint.rs => src/entrypoint.rs +32 -4
@@ 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;

Do not follow this link