add energy to amplitude (#457)

- [x] no changelog update needed
This commit is contained in:
Corwin 2023-07-19 20:36:54 +01:00 committed by GitHub
commit 2d53977c49
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 93 additions and 9 deletions

Binary file not shown.

View file

@ -7,6 +7,8 @@
extern crate alloc; extern crate alloc;
use core::ops::Range;
use agb::{ use agb::{
display::{ display::{
self, self,
@ -33,6 +35,7 @@ struct Saw {
rotation_speed: Number, rotation_speed: Number,
} }
#[derive(Clone, Copy)]
enum Colour { enum Colour {
Red, Red,
Blue, Blue,
@ -49,6 +52,7 @@ struct SpriteCache {
blue: SpriteVram, blue: SpriteVram,
red: SpriteVram, red: SpriteVram,
numbers: Box<[SpriteVram]>, numbers: Box<[SpriteVram]>,
bars: [Box<[SpriteVram]>; 2],
} }
#[derive(Clone, Copy, PartialEq, Eq)] #[derive(Clone, Copy, PartialEq, Eq)]
@ -57,6 +61,41 @@ enum DrawDirection {
Right, Right,
} }
fn draw_bar(
position: Vector2D<i32>,
length: usize,
colour: Colour,
oam: &mut OamIterator,
sprite_cache: &SpriteCache,
) -> Option<()> {
let length = length as i32;
let number_of_sprites = length / 8;
let size_of_last = length % 8;
let sprites = match colour {
Colour::Red => &sprite_cache.bars[0],
Colour::Blue => &sprite_cache.bars[1],
};
for sprite_idx in 0..number_of_sprites {
let mut object = ObjectUnmanaged::new(sprites[0].clone());
object
.show()
.set_position(position + (sprite_idx * 8, 0).into());
oam.next()?.set(&object);
}
if size_of_last != 0 {
let mut object = ObjectUnmanaged::new(sprites[8 - size_of_last as usize].clone());
object
.show()
.set_position(position + (number_of_sprites * 8, 0).into());
oam.next()?.set(&object);
}
Some(())
}
fn draw_number( fn draw_number(
mut number: u32, mut number: u32,
position: Vector2D<i32>, position: Vector2D<i32>,
@ -97,23 +136,38 @@ impl SpriteCache {
const SPRITES: &Graphics = include_aseprite!( const SPRITES: &Graphics = include_aseprite!(
"gfx/circles.aseprite", "gfx/circles.aseprite",
"gfx/saw.aseprite", "gfx/saw.aseprite",
"gfx/numbers.aseprite" "gfx/numbers.aseprite",
"gfx/bar.aseprite"
); );
fn generate_sprites(
tag: &'static Tag,
range: Range<usize>,
loader: &mut SpriteLoader,
) -> Box<[SpriteVram]> {
range
.map(|x| tag.sprite(x))
.map(|x| loader.get_vram_sprite(x))
.collect::<Vec<_>>()
.into_boxed_slice()
}
const NUMBERS: &Tag = SPRITES.tags().get("numbers"); const NUMBERS: &Tag = SPRITES.tags().get("numbers");
const BLUE_CIRCLE: &Sprite = SPRITES.tags().get("Blue").sprite(0); const BLUE_CIRCLE: &Sprite = SPRITES.tags().get("Blue").sprite(0);
const RED_CIRCLE: &Sprite = SPRITES.tags().get("Red").sprite(0); const RED_CIRCLE: &Sprite = SPRITES.tags().get("Red").sprite(0);
const SAW: &Sprite = SPRITES.tags().get("Saw").sprite(0); const SAW: &Sprite = SPRITES.tags().get("Saw").sprite(0);
const BAR_RED: &Tag = SPRITES.tags().get("Red Bar");
const BAR_BLUE: &Tag = SPRITES.tags().get("Blue Bar");
Self { Self {
saw: loader.get_vram_sprite(SAW), saw: loader.get_vram_sprite(SAW),
blue: loader.get_vram_sprite(BLUE_CIRCLE), blue: loader.get_vram_sprite(BLUE_CIRCLE),
red: loader.get_vram_sprite(RED_CIRCLE), red: loader.get_vram_sprite(RED_CIRCLE),
numbers: (0..10) numbers: generate_sprites(NUMBERS, 0..10, loader),
.map(|x| NUMBERS.sprite(x)) bars: [
.map(|x| loader.get_vram_sprite(x)) generate_sprites(BAR_RED, 0..8, loader),
.collect::<Vec<_>>() generate_sprites(BAR_BLUE, 0..8, loader),
.into_boxed_slice(), ],
} }
} }
} }
@ -127,6 +181,7 @@ struct Game {
input: ButtonController, input: ButtonController,
frame_since_last_saw: i32, frame_since_last_saw: i32,
alive_frames: u32, alive_frames: u32,
energy: Number,
} }
enum GameState { enum GameState {
@ -151,6 +206,7 @@ impl Game {
Game { Game {
input: agb::input::ButtonController::new(), input: agb::input::ButtonController::new(),
energy: finalised.max_energy,
settings: finalised, settings: finalised,
circles, circles,
saws: VecDeque::new(), saws: VecDeque::new(),
@ -164,9 +220,14 @@ impl Game {
fn frame(&mut self, sprite_cache: &SpriteCache) -> GameState { fn frame(&mut self, sprite_cache: &SpriteCache) -> GameState {
self.input.update(); self.input.update();
let (height, colour) = if self.input.is_pressed(Button::A) { let (height, colour) = if self.input.is_pressed(Button::A) && self.energy > 0.into() {
self.energy -= self.settings.energy_use_speed;
(self.settings.wave_height_ability, Colour::Blue) (self.settings.wave_height_ability, Colour::Blue)
} else { } else {
if self.input.is_released(Button::A) {
self.energy += self.settings.energy_recover_speed;
self.energy = self.energy.min(self.settings.max_energy);
}
(self.settings.wave_height_normal, Colour::Red) (self.settings.wave_height_normal, Colour::Red)
}; };
@ -288,6 +349,9 @@ struct Settings {
head_start_position: Vector2D<Number>, head_start_position: Vector2D<Number>,
wave_height_normal: Number, wave_height_normal: Number,
wave_height_ability: Number, wave_height_ability: Number,
max_energy: Number,
energy_use_speed: Number,
energy_recover_speed: Number,
} }
impl Settings { impl Settings {
@ -302,6 +366,9 @@ impl Settings {
frames_between_saws: self.frames_between_saws, frames_between_saws: self.frames_between_saws,
wave_height_ability: self.wave_height_ability, wave_height_ability: self.wave_height_ability,
wave_height_normal: self.wave_height_normal, wave_height_normal: self.wave_height_normal,
max_energy: self.max_energy,
energy_recover_speed: self.energy_recover_speed,
energy_use_speed: self.energy_use_speed,
} }
} }
} }
@ -313,6 +380,9 @@ struct FinalisedSettings {
frames_between_saws: i32, frames_between_saws: i32,
speed: Number, speed: Number,
number_of_circles: usize, number_of_circles: usize,
max_energy: Number,
energy_use_speed: Number,
energy_recover_speed: Number,
} }
pub fn main(mut gba: agb::Gba) -> ! { pub fn main(mut gba: agb::Gba) -> ! {
@ -335,28 +405,42 @@ pub fn main(mut gba: agb::Gba) -> ! {
head_start_position: (40, 100).into(), head_start_position: (40, 100).into(),
wave_height_normal: 20.into(), wave_height_normal: 20.into(),
wave_height_ability: 5.into(), wave_height_ability: 5.into(),
max_energy: 128.into(),
energy_use_speed: num!(0.5),
energy_recover_speed: 0.into(),
}); });
loop { loop {
let state = game.frame(&sprite_cache); let state = game.frame(&sprite_cache);
if game.alive_frames > max_score { if game.alive_frames > max_score {
max_score = game.alive_frames; max_score = game.alive_frames;
} }
let max_bar_width = display::WIDTH - 2;
let bar_width_pixels = (game.energy * max_bar_width) / game.settings.max_energy;
let bar_width_pixels = (bar_width_pixels + num!(0.5)).floor().max(0) as usize;
vblank.wait_for_vblank(); vblank.wait_for_vblank();
let oam_frame = &mut unmanaged.iter(); let oam_frame = &mut unmanaged.iter();
draw_number( draw_number(
max_score, max_score,
(display::WIDTH - 4, 1).into(), (display::WIDTH - 5, 2).into(),
oam_frame, oam_frame,
DrawDirection::Left, DrawDirection::Left,
&sprite_cache, &sprite_cache,
); );
draw_number( draw_number(
game.alive_frames, game.alive_frames,
(1, 1).into(), (2, 2).into(),
oam_frame, oam_frame,
DrawDirection::Right, DrawDirection::Right,
&sprite_cache, &sprite_cache,
); );
draw_bar(
(1, 1).into(),
bar_width_pixels,
game.circles.back().unwrap().colour,
oam_frame,
&sprite_cache,
);
game.render(oam_frame, &sprite_cache); game.render(oam_frame, &sprite_cache);
if let GameState::Loss(_) = state { if let GameState::Loss(_) = state {