From 399d80d72c1e176d7969a15c961445f454b4994b Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Fri, 8 Jan 2021 09:05:10 -0600 Subject: [PATCH] load animation for slider ball --- src/game.rs | 29 +++++++++++------ src/main.rs | 5 +-- src/skin.rs | 91 ++++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 98 insertions(+), 27 deletions(-) diff --git a/src/game.rs b/src/game.rs index 3ae9aa1..e449733 100644 --- a/src/game.rs +++ b/src/game.rs @@ -26,8 +26,8 @@ pub struct Game { song: Option, beatmap: Beatmap, hit_objects: Vec, - skin: Skin, - + pub skin: Skin, + frame: usize, slider_cache: SliderCache, } @@ -45,6 +45,7 @@ impl Game { hit_objects, song: None, skin, + frame: 0, slider_cache: SliderCache::default(), }) } @@ -60,7 +61,7 @@ impl Game { let dir = path.parent().unwrap(); let song = Sound::create(dir.join(&self.beatmap.audio_filename))?; - // song.set_position(36.5)?; + song.set_position(113.0)?; self.song = Some(song); Ok(()) @@ -79,6 +80,7 @@ impl Game { fn priv_draw(&mut self, ctx: &mut Context) -> Result<()> { // TODO: lol const PLAYFIELD_BOUNDS: Rect = Rect::new(112.0, 112.0, 800.0, 600.0); + const SEEKER_BOUNDS: Rect = Rect::new(46.0, 722.0, 932.0, 36.0); graphics::clear(ctx, [0.0, 0.0, 0.0, 1.0].into()); @@ -176,15 +178,21 @@ impl Game { PLAYFIELD_BOUNDS.x + osupx_scale_x * pos.0 as f32, PLAYFIELD_BOUNDS.y + osupx_scale_y * pos.1 as f32, ]; - let ball = Mesh::new_circle( + self.skin.sliderb.draw_frame( ctx, - DrawMode::Fill(FillOptions::default()), - ball_pos, - cs_real, - 1.0, - graphics::WHITE, + (cs_real * 2.0, cs_real * 2.0), + DrawParam::default().dest(ball_pos), + (travel_percent / 0.25) as usize, )?; - graphics::draw(ctx, &ball, DrawParam::default())?; + // let ball = Mesh::new_circle( + // ctx, + // DrawMode::Fill(FillOptions::default()), + // ball_pos, + // cs_real, + // 1.0, + // graphics::WHITE, + // )?; + // graphics::draw(ctx, &ball, DrawParam::default())?; } } @@ -212,6 +220,7 @@ impl Game { } graphics::present(ctx)?; + self.frame += 1; Ok(()) } } diff --git a/src/main.rs b/src/main.rs index 24d3950..13d9874 100644 --- a/src/main.rs +++ b/src/main.rs @@ -35,11 +35,12 @@ fn main() -> Result<()> { .window_setup(WindowSetup::default().title("OSU editor")) .window_mode(WindowMode::default().dimensions(1024.0, 768.0)); - let (ctx, event_loop) = &mut cb.build()?; + let (mut ctx, mut event_loop) = cb.build()?; let mut game = Game::new()?; + game.skin.load_all(&mut ctx)?; let path = env::args().nth(1).unwrap(); game.load_beatmap(path)?; - event::run(ctx, event_loop, &mut game)?; + event::run(&mut ctx, &mut event_loop, &mut game)?; Ok(()) } diff --git a/src/skin.rs b/src/skin.rs index 4ed9315..1454d48 100644 --- a/src/skin.rs +++ b/src/skin.rs @@ -8,7 +8,7 @@ use ggez::{ }; macro_rules! create_skin { - ($([$name:ident]),* $(,)?) => { + ($([$name:ident, $animatable:expr $(,)?]),* $(,)?) => { pub struct Skin { $( pub $name: Texture, @@ -18,40 +18,80 @@ macro_rules! create_skin { impl Skin { pub fn new() -> Self { Skin { - $($name: Texture::with_path(concat!("/", stringify!($name), ".png")),)* + $($name: Texture::with_name(stringify!($name), $animatable),)* } } + + // TODO: do this asynchronously? + pub fn load_all(&mut self, ctx: &mut Context) -> Result<()> { + $( + self.$name.load(ctx)?; + )* + Ok(()) + } } } } create_skin! { - [approachcircle], - [hitcircle], - [hitcircleoverlay], + [approachcircle, false], + [hitcircle, false], + [hitcircleoverlay, false], + [sliderb, true], } pub struct Texture { - path: PathBuf, + name: &'static str, image: Option, + animatable: bool, + animation: Vec, } impl Texture { - pub fn with_path(path: impl AsRef) -> Self { + pub fn with_name(name: &'static str, animatable: bool) -> Self { Texture { - path: path.as_ref().to_path_buf(), + name, image: None, + animatable, + animation: vec![], } } - pub fn draw(&mut self, ctx: &mut Context, size: (f32, f32), param: DrawParam) -> Result<()> { - let image = if self.image.is_some() { - self.image.as_ref().unwrap() - } else { - self.image = Some(Image::new(ctx, &self.path)?); - self.image.as_ref().unwrap() - }; + pub fn load(&mut self, ctx: &mut Context) -> Result<()> { + let mut found = false; + if self.animatable { + // god fucking dammit + let hyphen = if self.name == "sliderb" { "" } else { "-" }; + self.animation.clear(); + let mut curr = 0; + loop { + let image = match Image::new(ctx, &format!("/{}{}{}.png", self.name, hyphen, curr)) + { + Ok(v) => v, + Err(_) => break, + }; + self.animation.push(image); + found = true; + curr += 1; + } + println!("loaded {} images!", curr); + } + + if !found { + self.image = Some(Image::new(ctx, &format!("/{}.png", self.name))?); + } + + Ok(()) + } + + fn draw_image( + &self, + ctx: &mut Context, + image: &Image, + size: (f32, f32), + param: DrawParam, + ) -> Result<()> { let random_constant = 1.35; let x_scale = random_constant * size.0 / image.width() as f32; let y_scale = random_constant * size.1 / image.height() as f32; @@ -64,4 +104,25 @@ impl Texture { )?; Ok(()) } + + pub fn draw(&mut self, ctx: &mut Context, size: (f32, f32), param: DrawParam) -> Result<()> { + let image = self.image.as_ref().unwrap(); + self.draw_image(ctx, image, size, param) + } + + pub fn draw_frame( + &mut self, + ctx: &mut Context, + size: (f32, f32), + param: DrawParam, + frame: usize, + ) -> Result<()> { + let image = if self.animatable { + let ct = frame % self.animation.len(); + self.animation.get(ct).unwrap() + } else { + self.image.as_ref().unwrap() + }; + self.draw_image(ctx, image, size, param) + } }