use agb::fixnum::{Vector2D, vec2};
use agb::input::{Button, ButtonController};
#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
pub enum Direction {
Up,
Down,
Left,
Right,
}
impl Direction {
pub fn from_input(buttons: &ButtonController) -> Option<Direction> {
if buttons.is_pressed(Button::Up) {
Some(Direction::Up)
} else if buttons.is_pressed(Button::Down) {
Some(Direction::Down)
} else if buttons.is_pressed(Button::Left) {
Some(Direction::Left)
} else if buttons.is_pressed(Button::Right) {
Some(Direction::Right)
} else {
None
}
}
pub fn from_recent_input(buttons: &ButtonController) -> Option<Direction> {
if buttons.is_just_pressed(Button::Up) {
Some(Direction::Up)
} else if buttons.is_just_pressed(Button::Down) {
Some(Direction::Down)
} else if buttons.is_just_pressed(Button::Left) {
Some(Direction::Left)
} else if buttons.is_just_pressed(Button::Right) {
Some(Direction::Right)
} else {
None
}
}
#[inline]
pub const fn opposite(self) -> Direction {
match self {
Direction::Up => Direction::Down,
Direction::Down => Direction::Up,
Direction::Left => Direction::Right,
Direction::Right => Direction::Left,
}
}
#[inline]
pub const fn to_vector(self) -> Vector2D<i32> {
match self {
Direction::Up => vec2(0, -1),
Direction::Down => vec2(0, 1),
Direction::Left => vec2(-1, 0),
Direction::Right => vec2(1, 0),
}
}
#[inline]
pub const fn is_horizontal(self) -> bool {
matches!(self, Direction::Left | Direction::Right)
}
#[inline]
pub const fn is_vertical(self) -> bool {
!self.is_horizontal()
}
}
impl From<Direction> for Vector2D<i32> {
fn from(value: Direction) -> Self {
value.to_vector()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test_case]
fn opposite_and_vector(_gba: &mut agb::Gba) {
for dir in [
Direction::Up,
Direction::Down,
Direction::Left,
Direction::Right,
] {
assert_eq!(dir.opposite().opposite(), dir);
assert_eq!(dir.to_vector() + dir.opposite().to_vector(), vec2(0, 0));
assert_ne!(dir.is_horizontal(), dir.is_vertical());
}
assert_eq!(Direction::Up.to_vector(), vec2(0, -1));
assert_eq!(Vector2D::from(Direction::Right), vec2(1, 0));
}
}