use crate::{Fixed, goose_sprites}; use agb::display::object::Object; use agb::display::{GraphicsFrame, HEIGHT, Priority, WIDTH}; use agb::fixnum::{Num, Vector2D, num, vec2}; use agb::input::Button; pub enum GameState { Start, Playing, GameOver, } pub struct GameLoop { pub score: u16, pub game_state: GameState, } impl GameLoop { pub fn new() -> Self { Self { score: 0, game_state: GameState::Start, } } pub fn run(&mut self, gba: &mut agb::Gba) { let mut gfx = gba.graphics.get(); let mut button_controller = agb::input::ButtonController::new(); let mut goose = Goose::new(); loop { button_controller.update(); let mut frame = gfx.frame(); let just_pressed = button_controller.is_just_pressed(Button::A); goose.move_goose(just_pressed); goose.show(&mut frame); frame.commit(); } } } /// I really don't have a better name for these #[derive(Copy, Clone)] pub enum GooseState { Zero = 0, One = 1, Two = 2, Three = 3, } pub struct Goose { pos: Vector2D, velocity: Vector2D, current_state: GooseState, //Should increase every game play loop and reset at 64 tick_counter: u8, } impl Goose { pub fn new() -> Self { Self { pos: vec2(num!(5), num!(5)), velocity: vec2(num!(0.20), num!(0)), current_state: GooseState::Zero, tick_counter: 0, } } pub fn show(&mut self, frame: &mut GraphicsFrame) { let _ = Object::new(goose_sprites::GOOSE.sprite(self.current_state as usize)) .set_pos(self.pos.round()) .set_priority(Priority::P1) .show(frame); } fn animate(&mut self) { // Advance animation every 8 ticks self.tick_counter = self.tick_counter.wrapping_add(1); if self.tick_counter % 8 == 0 { self.current_state = match self.current_state { GooseState::Zero => GooseState::One, GooseState::One => GooseState::Two, GooseState::Two => GooseState::Three, GooseState::Three => GooseState::Zero, } } //Just a catch to not let that number get too big if self.tick_counter >= 64 { self.tick_counter = 0; } } fn reset(&mut self) { self.pos = vec2(num!(5), num!(5)); self.velocity = vec2(num!(0.20), num!(0)); } pub fn move_goose(&mut self, button_pressed: bool) { //If the button is pressed, go up a bit if button_pressed { self.velocity.y = num!(-1); } else { self.velocity.y += num!(0.02); } self.pos += self.velocity; //Right now just cycling through may change animations around self.animate(); //Keep in frame right now. Will later do the scrolling map thing if self.pos.y < num!(0) { self.pos.y = num!(0); self.velocity.y = num!(0); } if self.pos.y >= num!(HEIGHT) { //TODO call game end here later self.reset(); } // Keep X within screen horizontally (optional: clamp) if self.pos.x < num!(0) { self.pos.x = num!(0); } let max_x = num!(WIDTH - 1); if self.pos.x > max_x { self.pos.x = max_x; } } }