mara2/src/lib.rs

184 lines
4.9 KiB
Rust
Raw Normal View History

2022-03-07 02:10:49 +00:00
#[cfg(feature = "buddy-alloc")]
mod alloc;
mod sh0rk;
mod sprites;
use fastrand::Rng;
use sh0rk::{
palette,
sys::*,
Direction::{self, *},
Rect,
Point,
};
2022-03-07 02:10:49 +00:00
static mut GAME: Game = Game::new();
struct Game {
frame_count: u32,
prev_gamepad: u8,
rng: Option<Rng>,
mai_position: Point,
mara_position: Point,
mara_frame: u32,
mara_dir: Direction,
mara_speed: i32,
bonk_timer: Option<u8>,
gate_count: u8,
gate_pos: Point,
2022-03-07 02:10:49 +00:00
}
impl Game {
const fn new() -> Self {
Self {
frame_count: 0,
prev_gamepad: 0,
rng: None,
mai_position: Point { x: 76, y: 32 },
mara_position: Point { x: 32, y: 90 },
2022-03-07 02:10:49 +00:00
mara_frame: 0,
mara_dir: Right,
mara_speed: 0,
bonk_timer: None,
gate_count: 4,
gate_pos: Point { x: 40, y: 64 },
2022-03-07 02:10:49 +00:00
}
}
fn bonk(&mut self) {
if self.bonk_timer.is_some() {
return;
}
2022-03-07 02:10:49 +00:00
tone(220 | (40 << 16), 6 | (6 << 8), 50, TONE_TRIANGLE);
self.bonk_timer = Some(12);
}
2022-03-07 02:10:49 +00:00
fn mara_walk(&mut self) {
if self.mara_speed == 0 {
return;
}
2022-03-07 02:10:49 +00:00
if self.frame_count % 15 == 0 {
self.mara_frame = if self.mara_frame == 1 { 0 } else { 1 };
}
if self.frame_count % 4 == 0 {
if self.mara_dir == Right && self.mara_position.x >= 144 {
self.mara_speed = 0;
self.mara_position.x = 144;
self.bonk();
2022-03-07 02:10:49 +00:00
}
if self.mara_dir == Down && self.mara_position.y >= 120 {
self.mara_speed = 0;
self.mara_position.y = 120;
self.bonk();
2022-03-07 02:10:49 +00:00
}
if self.mara_dir == Left && self.mara_position.x <= 0 {
self.mara_speed = 0;
self.mara_position.x = 0;
self.bonk();
2022-03-07 02:10:49 +00:00
}
if self.mara_dir == Up && self.mara_position.y <= 64 {
self.mara_speed = 0;
self.mara_position.y = 64;
self.bonk();
2022-03-07 02:10:49 +00:00
}
match self.mara_dir {
Left => self.mara_position.x -= self.mara_speed,
Right => self.mara_position.x += self.mara_speed,
Up => self.mara_position.y -= self.mara_speed,
Down => self.mara_position.y += self.mara_speed,
2022-03-07 02:10:49 +00:00
};
}
}
fn update(&mut self) {
self.frame_count += 1;
if let Some(rem) = self.bonk_timer {
if rem == 0 {
self.bonk_timer = None;
} else {
self.bonk_timer = Some(rem - 1);
}
}
self.mara_speed = 0;
let gamepad = unsafe { *GAMEPAD1 };
let just_pressed = gamepad & (gamepad ^ self.prev_gamepad);
let speed = if just_pressed & BUTTON_2 != 0 { 4 } else { 2 };
if gamepad & BUTTON_UP != 0 {
self.mara_dir = Up;
self.mara_speed = speed;
}
if gamepad & BUTTON_DOWN != 0 {
self.mara_dir = Down;
self.mara_speed = speed;
}
if gamepad & BUTTON_LEFT != 0 {
self.mara_dir = Left;
self.mara_speed = speed;
}
if gamepad & BUTTON_RIGHT != 0 {
self.mara_dir = Right;
self.mara_speed = speed;
}
self.prev_gamepad = gamepad;
self.mara_walk();
let player = Rect { base: self.mara_position.clone(), width: 16, height: 16 };
let gate = Rect { base: self.gate_pos.clone(), width: 12, height: 4 * self.gate_count as i32 };
if player.collides(&gate) {
self.mara_speed = 0;
match self.mara_dir {
Right => self.mara_position = self.mara_position.add((-2, 0)),
Left => self.mara_position = self.mara_position.add((2, 0)),
Up => self.mara_position = self.mara_position.add((0, 2)),
Down => self.mara_position = self.mara_position.add((0, -2)),
};
self.bonk();
}
// draw
for i in 0..self.gate_count {
let mut gate = self.gate_pos.clone();
gate.y = gate.y + (sprites::GATE.height * i as u32) as i32;
sprites::GATE.draw(gate, 0);
}
palette::set_draw_color(4);
line(
self.gate_pos.x + 1,
self.gate_pos.y - 1,
self.gate_pos.x + 10,
self.gate_pos.y - 1,
);
palette::set_draw_color(2);
text("Mara: Sh0rk of\nJustice 2", 10, 10);
palette::set_draw_color(4);
text("From Within, 2022", 10, 144);
sprites::MAI.draw(self.mai_position, 0);
sprites::MARA.draw(self.mara_dir, self.mara_frame, self.mara_position, 0);
2022-03-07 02:10:49 +00:00
}
}
#[no_mangle]
unsafe fn start() {
palette::en4();
GAME.rng = Some(Rng::with_seed(420));
}
#[no_mangle]
unsafe fn update() {
GAME.update();
}