Animated backgrounds? #787
-
I have a background in What is the easiest way? my code uses the following to show and hide the backgrounds: pub struct Background<'a> {
map_loan: MapLoan<'a, RegularMap>,
tile_data: &'static TileData,
}
impl<'a> Background<'a> {
pub fn show<'b: 'a>(&mut self, gfx: &Gfx) {
let vram = unsafe { &mut *gfx.vram.get() };
self.map_loan.set_scroll_pos((0i16, 0));
vram.set_background_palettes(backgrounds::PALETTES);
self.map_loan.set_visible(false);
self.map_loan.fill_with(vram, self.tile_data);
self.map_loan.commit(vram);
self.map_loan.set_visible(true);
}
pub fn hide(&mut self) {
self.map_loan.set_visible(false);
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
I've ended tinkering my own animation system for the background: pub struct AnimatedBackground<'a> {
frames: &'static [&'static TileData],
palettes: &'static [Palette16],
priority: Priority,
last_background: Option<Background<'a>>,
}
impl<'a> AnimatedBackground<'a> {
pub fn set_frame(&mut self, gfx: &'a Gfx, frame: u8) {
let mut new_bg = gfx.load_bg(self.priority, self.palettes, &self.frames[frame as usize]);
new_bg.show(gfx);
if let Some(mut bg) = core::mem::take(&mut self.last_background) {
bg.destroy(gfx);
bg.hide();
}
self.last_background = Some(new_bg);
}
pub fn end(&mut self, gfx: &Gfx) {
if let Some(mut bg) = core::mem::take(&mut self.last_background) {
bg.destroy(gfx);
bg.hide();
}
}
} And then using it like: static TITLE_FRAMES: [&'static agb::display::tile_data::TileData; 9] = [
&core::bg::title::frame1,
&core::bg::title::frame2,
&core::bg::title::frame3,
&core::bg::title::frame4,
&core::bg::title::frame5,
&core::bg::title::frame6,
&core::bg::title::frame7,
&core::bg::title::frame8,
&core::bg::title::frame9,
];
let mut title = gfx.new_animated_bg(Priority::P0, &core::bg::title::PALETTES, &TITLE_FRAMES);
title.set_frame(&gfx, 0);
sfx.frame();
splash.destroy(&gfx);
splash.hide();
sleep(Duration::Milliseconds(2200), || sfx.frame());
title.set_frame(&gfx, 1);
sleep(Duration::Milliseconds(2200), || sfx.frame());
title.set_frame(&gfx, 2);
sleep(Duration::Milliseconds(1600), || sfx.frame());
title.set_frame(&gfx, 3);
sleep(Duration::Milliseconds(250), || sfx.frame());
title.set_frame(&gfx, 4);
sleep(Duration::Milliseconds(250), || sfx.frame());
title.set_frame(&gfx, 5);
sleep(Duration::Milliseconds(250), || sfx.frame());
title.set_frame(&gfx, 6);
sleep(Duration::Milliseconds(250), || sfx.frame());
title.set_frame(&gfx, 7);
sleep(Duration::Milliseconds(250), || sfx.frame());
title.set_frame(&gfx, 8); Obviously, that forced me to flatten the background include_background_gfx!(title,
frame1 => deduplicate "assets/main_menu1.png",
frame2 => deduplicate "assets/main_menu2.png",
frame3 => deduplicate "assets/main_menu3.png",
frame4 => deduplicate "assets/main_menu4.png",
frame5 => deduplicate "assets/main_menu5.png",
frame6 => deduplicate "assets/main_menu6.png",
frame7 => deduplicate "assets/main_menu7.png",
frame8 => deduplicate "assets/main_menu8.png",
frame9 => deduplicate "assets/main_menu9.png",
); |
Beta Was this translation helpful? Give feedback.
-
Animating a full background is probably a bit too slow with agb (and without the agb abstractions, uses up quite a lot of the CPU time you have for a single frame). I managed to get an example where I could play bad apple at 30fps but no faster by updating half per frame across 2 backgrounds (because I would normally only replace a subset of the tiles, and do the rest of the animation with objects (which appears to be how most commercial games did this too). You can see in the animated tiles example here: https://agbrs.dev/examples/animatedbackground, you can replace a single tile which may be repeated across the frame in many locations with a different one. That is a very fast operation and allows for full screen animations without using very much of the CPU, although they are a little more restrictive since you can only swap entire tiles. |
Beta Was this translation helpful? Give feedback.
Animating a full background is probably a bit too slow with agb (and without the agb abstractions, uses up quite a lot of the CPU time you have for a single frame). I managed to get an example where I could play bad apple at 30fps but no faster by updating half per frame across 2 backgrounds (because
commit
can be quite an expensive operation).I would normally only replace a subset of the tiles, and do the rest of the animation with objects (which appears to be how most commercial games did this too). You can see in the animated tiles example here: https://agbrs.dev/examples/animatedbackground, you can replace a single tile which may be repeated across the frame in many locations with a …