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>,
|
song: Option<Sound>,
|
||||||
beatmap: Beatmap,
|
beatmap: Beatmap,
|
||||||
hit_objects: Vec<HitObject>,
|
hit_objects: Vec<HitObject>,
|
||||||
skin: Skin,
|
pub skin: Skin,
|
||||||
|
frame: usize,
|
||||||
slider_cache: SliderCache,
|
slider_cache: SliderCache,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ impl Game {
|
||||||
hit_objects,
|
hit_objects,
|
||||||
song: None,
|
song: None,
|
||||||
skin,
|
skin,
|
||||||
|
frame: 0,
|
||||||
slider_cache: SliderCache::default(),
|
slider_cache: SliderCache::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -60,7 +61,7 @@ impl Game {
|
||||||
let dir = path.parent().unwrap();
|
let dir = path.parent().unwrap();
|
||||||
|
|
||||||
let song = Sound::create(dir.join(&self.beatmap.audio_filename))?;
|
let song = Sound::create(dir.join(&self.beatmap.audio_filename))?;
|
||||||
// song.set_position(36.5)?;
|
song.set_position(113.0)?;
|
||||||
self.song = Some(song);
|
self.song = Some(song);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -79,6 +80,7 @@ impl Game {
|
||||||
fn priv_draw(&mut self, ctx: &mut Context) -> Result<()> {
|
fn priv_draw(&mut self, ctx: &mut Context) -> Result<()> {
|
||||||
// TODO: lol
|
// TODO: lol
|
||||||
const PLAYFIELD_BOUNDS: Rect = Rect::new(112.0, 112.0, 800.0, 600.0);
|
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());
|
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.x + osupx_scale_x * pos.0 as f32,
|
||||||
PLAYFIELD_BOUNDS.y + osupx_scale_y * pos.1 as f32,
|
PLAYFIELD_BOUNDS.y + osupx_scale_y * pos.1 as f32,
|
||||||
];
|
];
|
||||||
let ball = Mesh::new_circle(
|
self.skin.sliderb.draw_frame(
|
||||||
ctx,
|
ctx,
|
||||||
DrawMode::Fill(FillOptions::default()),
|
(cs_real * 2.0, cs_real * 2.0),
|
||||||
ball_pos,
|
DrawParam::default().dest(ball_pos),
|
||||||
cs_real,
|
(travel_percent / 0.25) as usize,
|
||||||
1.0,
|
|
||||||
graphics::WHITE,
|
|
||||||
)?;
|
)?;
|
||||||
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)?;
|
graphics::present(ctx)?;
|
||||||
|
self.frame += 1;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,11 +35,12 @@ fn main() -> Result<()> {
|
||||||
.window_setup(WindowSetup::default().title("OSU editor"))
|
.window_setup(WindowSetup::default().title("OSU editor"))
|
||||||
.window_mode(WindowMode::default().dimensions(1024.0, 768.0));
|
.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()?;
|
let mut game = Game::new()?;
|
||||||
|
game.skin.load_all(&mut ctx)?;
|
||||||
let path = env::args().nth(1).unwrap();
|
let path = env::args().nth(1).unwrap();
|
||||||
game.load_beatmap(path)?;
|
game.load_beatmap(path)?;
|
||||||
event::run(ctx, event_loop, &mut game)?;
|
event::run(&mut ctx, &mut event_loop, &mut game)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
91
src/skin.rs
91
src/skin.rs
|
@ -8,7 +8,7 @@ use ggez::{
|
||||||
};
|
};
|
||||||
|
|
||||||
macro_rules! create_skin {
|
macro_rules! create_skin {
|
||||||
($([$name:ident]),* $(,)?) => {
|
($([$name:ident, $animatable:expr $(,)?]),* $(,)?) => {
|
||||||
pub struct Skin {
|
pub struct Skin {
|
||||||
$(
|
$(
|
||||||
pub $name: Texture,
|
pub $name: Texture,
|
||||||
|
@ -18,40 +18,80 @@ macro_rules! create_skin {
|
||||||
impl Skin {
|
impl Skin {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Skin {
|
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! {
|
create_skin! {
|
||||||
[approachcircle],
|
[approachcircle, false],
|
||||||
[hitcircle],
|
[hitcircle, false],
|
||||||
[hitcircleoverlay],
|
[hitcircleoverlay, false],
|
||||||
|
[sliderb, true],
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Texture {
|
pub struct Texture {
|
||||||
path: PathBuf,
|
name: &'static str,
|
||||||
image: Option<Image>,
|
image: Option<Image>,
|
||||||
|
animatable: bool,
|
||||||
|
animation: Vec<Image>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Texture {
|
impl Texture {
|
||||||
pub fn with_path(path: impl AsRef<Path>) -> Self {
|
pub fn with_name(name: &'static str, animatable: bool) -> Self {
|
||||||
Texture {
|
Texture {
|
||||||
path: path.as_ref().to_path_buf(),
|
name,
|
||||||
image: None,
|
image: None,
|
||||||
|
animatable,
|
||||||
|
animation: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(&mut self, ctx: &mut Context, size: (f32, f32), param: DrawParam) -> Result<()> {
|
pub fn load(&mut self, ctx: &mut Context) -> Result<()> {
|
||||||
let image = if self.image.is_some() {
|
let mut found = false;
|
||||||
self.image.as_ref().unwrap()
|
if self.animatable {
|
||||||
} else {
|
// god fucking dammit
|
||||||
self.image = Some(Image::new(ctx, &self.path)?);
|
let hyphen = if self.name == "sliderb" { "" } else { "-" };
|
||||||
self.image.as_ref().unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
|
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 random_constant = 1.35;
|
||||||
let x_scale = random_constant * size.0 / image.width() as f32;
|
let x_scale = random_constant * size.0 / image.width() as f32;
|
||||||
let y_scale = random_constant * size.1 / image.height() as f32;
|
let y_scale = random_constant * size.1 / image.height() as f32;
|
||||||
|
@ -64,4 +104,25 @@ impl Texture {
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
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