load animation for slider ball
This commit is contained in:
parent
ad0de3d46f
commit
399d80d72c
3 changed files with 98 additions and 27 deletions
29
src/game.rs
29
src/game.rs
|
@ -26,8 +26,8 @@ pub struct Game {
|
|||
song: Option<Sound>,
|
||||
beatmap: Beatmap,
|
||||
hit_objects: Vec<HitObject>,
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
91
src/skin.rs
91
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<Image>,
|
||||
animatable: bool,
|
||||
animation: Vec<Image>,
|
||||
}
|
||||
|
||||
impl Texture {
|
||||
pub fn with_path(path: impl AsRef<Path>) -> 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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue