My actor.rpg avatar walking around on a GBA game
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 122 lines 3.1 kB view raw
1#![no_std] 2#![no_main] 3#![cfg_attr(test, feature(custom_test_frameworks))] 4#![cfg_attr(test, reexport_test_harness_main = "test_main")] 5#![cfg_attr(test, test_runner(agb::test_runner::test_runner))] 6 7extern crate alloc; 8 9use agb::{ 10 display::{ 11 HEIGHT, WIDTH, 12 object::{Object, Sprite, Tag}, 13 }, 14 fixnum::{Num, Vector2D, num, vec2}, 15 include_aseprite, 16 input::ButtonController, 17}; 18 19include_aseprite!(mod sprites, "gfx/pumpkin_head.aseprite"); 20use sprites::{FORWARD, LEFT, REVERSE, RIGHT}; 21 22type Number = Num<i32, 8>; 23 24#[derive(Clone, Copy)] 25enum Facing { 26 Forward, 27 Reverse, 28 Left, 29 Right, 30} 31 32impl Facing { 33 fn tag(self) -> &'static Tag { 34 match self { 35 Facing::Forward => &FORWARD, 36 Facing::Reverse => &REVERSE, 37 Facing::Left => &LEFT, 38 Facing::Right => &RIGHT, 39 } 40 } 41} 42 43const SPEED: Number = num!(0.75); 44const SPRITE_WIDTH: i32 = 32; 45const SPRITE_HEIGHT: i32 = 64; 46 47// The sprite is closer to 32x47. But the gba doesn't like that sprite size so adding some padding 48const SPRITE_TOP_PADDING: i32 = 17; 49const VISIBLE_HEIGHT: i32 = SPRITE_HEIGHT - SPRITE_TOP_PADDING; 50const FRAMES_PER_STEP: usize = 8; 51 52#[agb::entry] 53fn main(gba: agb::Gba) -> ! { 54 run(gba); 55} 56 57fn run(mut gba: agb::Gba) -> ! { 58 let mut gfx = gba.graphics.get(); 59 let mut input = ButtonController::new(); 60 61 let mut position: Vector2D<Number> = vec2( 62 Number::new((WIDTH - SPRITE_WIDTH) / 2), 63 Number::new((HEIGHT - VISIBLE_HEIGHT) / 2 - SPRITE_TOP_PADDING), 64 ); 65 let mut facing = Facing::Forward; 66 let mut walk_frames: usize = 0; 67 68 let max_x = Number::new(WIDTH - SPRITE_WIDTH); 69 let max_y = Number::new(HEIGHT - SPRITE_HEIGHT); 70 let min_y = Number::new(-SPRITE_TOP_PADDING); 71 72 loop { 73 input.update(); 74 75 let dx = input.x_tri() as i32; 76 let dy = input.y_tri() as i32; 77 let moving = dx != 0 || dy != 0; 78 79 if moving { 80 facing = if dy < 0 { 81 Facing::Reverse 82 } else if dy > 0 { 83 Facing::Forward 84 } else if dx < 0 { 85 Facing::Left 86 } else { 87 Facing::Right 88 }; 89 90 position.x += SPEED * dx; 91 position.y += SPEED * dy; 92 93 if position.x < num!(0.0) { 94 position.x = num!(0.0); 95 } 96 if position.y < min_y { 97 position.y = min_y; 98 } 99 if position.x > max_x { 100 position.x = max_x; 101 } 102 if position.y > max_y { 103 position.y = max_y; 104 } 105 106 walk_frames = walk_frames.wrapping_add(1); 107 } 108 109 let tag = facing.tag(); 110 let sprite: &'static Sprite = if moving { 111 tag.animation_sprite(walk_frames / FRAMES_PER_STEP) 112 } else { 113 tag.sprite(0) 114 }; 115 116 let mut frame = gfx.frame(); 117 Object::new(sprite) 118 .set_pos(position.floor()) 119 .show(&mut frame); 120 frame.commit(); 121 } 122}