💾 Archived View for devlog.thermokar.st › 2022-12-04.gmi captured on 2023-01-29 at 02:16:12. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
single-button gba rom
before i forget: advent of code has been going pretty well so far, i'm doing it in rust again this year.
okay, bootstrapping a simple one-button test rom in agb. step 1, scaffold.
git clone https://github.com/agbrs/template single-button-agb cd single-button-agb cargo run
agb is designed to integrate with aseprite, so i better get that set up. i've used it before but i don't think i own a licensed copy of it.
i just picked up aseprite on itch.io and spent a few minutes getting re-acquainted.
so my plan is to show a single sprite on the screen, and pressing the a button will cause the sprite to toggle. im not sure if it is a moment toggle, or if its only toggled while being held down.
mkdir gfx # set up two-frame aseprite with distinctly different images # and unique tag names
in the gba src:
const FACES: &Graphics = include_aseprite!("gfx/face.aseprite"); const HAPPY_FACE: &Tag = FACES.tags().get("Happy Face"); const SAD_FACE: &Tag = FACES.tags().get("Sad Face");
i have a simple demo working, i want to clean this up and then see about adding a sound effect when toggling the sprite.
i had a bit of a break for the last 45 mins, but came back and was able to use the agb built-in sound synthesis to play back a really terrible sounding sound clip.
#![no_std] #![no_main] #![cfg_attr(test, feature(custom_test_frameworks))] #![cfg_attr(test, reexport_test_harness_main = "test_main")] #![cfg_attr(test, test_runner(agb::test_runner::test_runner))] use agb::{ display::object::{Graphics, Tag}, include_aseprite, input::{Button, ButtonController}, sound, }; const FACES: &Graphics = include_aseprite!("gfx/face.aseprite"); const HAPPY_FACE: &Tag = FACES.tags().get("Happy Face"); const SAD_FACE: &Tag = FACES.tags().get("Sad Face"); const WIDTH: i32 = agb::display::WIDTH - 16; const HEIGHT: i32 = agb::display::HEIGHT - 16; struct Face { is_happy: bool, x: i32, y: i32, vel_x: i32, vel_y: i32, } impl Face { fn new() -> Face { Face { is_happy: false, x: 55, y: 55, vel_x: 1, vel_y: 1, } } fn tick(&mut self) -> () { self.x = (self.x + self.vel_x).clamp(0, WIDTH); self.y = (self.y + self.vel_y).clamp(0, HEIGHT); if self.x == 0 || self.x == WIDTH { self.vel_x = -self.vel_x; } if self.y == 0 || self.y == HEIGHT { self.vel_y = -self.vel_y; } } } #[agb::entry] fn main(mut gba: agb::Gba) -> ! { gba.sound.enable(); let object_controller = gba.display.object.get(); let mut input = ButtonController::new(); let mut face_data = Face::new(); let sad_face_sprite = SAD_FACE.sprite(0); let happy_face_sprite = HAPPY_FACE.sprite(0); let mut face_obj = object_controller.object_sprite(sad_face_sprite); loop { input.update(); if input.is_just_pressed(Button::A) { let face_sprite = match face_data.is_happy { true => sad_face_sprite, false => happy_face_sprite, }; let sprite = object_controller.sprite(face_sprite); face_obj.set_sprite(sprite); face_data.is_happy = !face_data.is_happy; gba.sound.noise().play_sound( Some(0), &sound::dmg::EnvelopeSettings::default(), 7, false, 1, ); } face_data.tick(); face_obj.set_x(face_data.x as u16).set_y(face_data.y as u16); agb::display::busy_wait_for_vblank(); object_controller.commit(); } }
uploaded to the gameSH and everything is great!
two things to look into:
© 2022 Matthew Ryan Dillon