implement scrolling using arrow keys
This commit is contained in:
parent
7060f21188
commit
f244d62a88
4 changed files with 74 additions and 7 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1072,7 +1072,7 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
|
|||
[[package]]
|
||||
name = "libosu"
|
||||
version = "0.0.15"
|
||||
source = "git+https://github.com/iptq/libosu?rev=7f5e8fd6bdf2798dd40df9595ce630ebc27ac13e#7f5e8fd6bdf2798dd40df9595ce630ebc27ac13e"
|
||||
source = "git+https://github.com/iptq/libosu?rev=7fbe7afbad55b25398062719ebaccbff0387d139#7fbe7afbad55b25398062719ebaccbff0387d139"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags",
|
||||
|
|
|
@ -4,6 +4,9 @@ version = "0.1.0"
|
|||
authors = ["Michael Zhang <mail@mzhang.io>"]
|
||||
edition = "2018"
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
"bass-sys",
|
||||
|
@ -21,4 +24,4 @@ structopt = "0.3.21"
|
|||
|
||||
[dependencies.libosu]
|
||||
git = "https://github.com/iptq/libosu"
|
||||
rev = "7f5e8fd6bdf2798dd40df9595ce630ebc27ac13e"
|
||||
rev = "7fbe7afbad55b25398062719ebaccbff0387d139"
|
||||
|
|
|
@ -19,6 +19,7 @@ use libosu::{
|
|||
hitobject::{HitObjectKind, SpinnerInfo},
|
||||
math::Point,
|
||||
spline::Spline,
|
||||
timing::TimingPointKind,
|
||||
};
|
||||
|
||||
use crate::audio::{AudioEngine, Sound};
|
||||
|
@ -26,7 +27,7 @@ use crate::beatmap::{BeatmapExt, STACK_DISTANCE};
|
|||
use crate::hitobject::HitObjectExt;
|
||||
use crate::skin::Skin;
|
||||
|
||||
pub const PLAYFIELD_BOUNDS: Rect = Rect::new(112.0, 112.0, 800.0, 600.0);
|
||||
pub const PLAYFIELD_BOUNDS: Rect = Rect::new(112.0, 122.0, 800.0, 600.0);
|
||||
|
||||
pub type SliderCache = HashMap<Vec<Point<i32>>, Spline>;
|
||||
|
||||
|
@ -274,6 +275,32 @@ impl Game {
|
|||
self.frame += 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn seek_by_steps(&self, n: i32) -> Result<()> {
|
||||
if let Some(song) = &self.song {
|
||||
let pos = song.position()?;
|
||||
let mut delta = None;
|
||||
for timing_point in self.beatmap.inner.timing_points.iter() {
|
||||
if let TimingPointKind::Uninherited(info) = &timing_point.kind {
|
||||
if pos > timing_point.time.as_seconds() {
|
||||
let diff = pos - timing_point.time.as_seconds();
|
||||
let tick = info.mpb / 1000.0 / info.meter as f64;
|
||||
if (diff / tick).abs() < 0.001 {
|
||||
delta = Some(n as f64 * tick);
|
||||
} else {
|
||||
let tick = info.mpb / 1000.0;
|
||||
delta = Some(n as f64 * tick);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(delta) = delta {
|
||||
song.set_position(pos + delta)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl EventHandler for Game {
|
||||
|
@ -287,7 +314,20 @@ impl EventHandler for Game {
|
|||
Space => self.toggle_playing(),
|
||||
Colon => {}
|
||||
_ => {}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn key_down_event(&mut self, _: &mut Context, keycode: KeyCode, _: KeyMods, _: bool) {
|
||||
use KeyCode::*;
|
||||
match keycode {
|
||||
Left => {
|
||||
self.seek_by_steps(-1);
|
||||
}
|
||||
Right => {
|
||||
self.seek_by_steps(1);
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
|
||||
fn draw(&mut self, ctx: &mut Context) -> GameResult {
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
use anyhow::Result;
|
||||
use ggez::{
|
||||
graphics::{self, DrawParam, Mesh, Rect},
|
||||
graphics::{self, Color, DrawParam, Mesh, Rect},
|
||||
nalgebra::Point2,
|
||||
Context,
|
||||
};
|
||||
use libosu::timing::TimingPointKind;
|
||||
|
||||
use super::Game;
|
||||
|
||||
pub const BOUNDS: Rect = Rect::new(46.0, 722.0, 932.0, 36.0);
|
||||
pub const BOUNDS: Rect = Rect::new(46.0, 732.0, 932.0, 36.0);
|
||||
|
||||
impl Game {
|
||||
pub(super) fn draw_seeker(&self, ctx: &mut Context) -> Result<()> {
|
||||
|
@ -24,7 +25,30 @@ impl Game {
|
|||
graphics::draw(ctx, &line, DrawParam::default())?;
|
||||
|
||||
if let Some(song) = &self.song {
|
||||
let percent = song.position()? / song.length()?;
|
||||
let len = song.length()?;
|
||||
|
||||
for timing_point in self.beatmap.inner.timing_points.iter() {
|
||||
let color = match timing_point.kind {
|
||||
TimingPointKind::Inherited(_) => Color::new(0.0, 1.0, 0.0, 0.5),
|
||||
TimingPointKind::Uninherited(_) => Color::new(1.0, 0.0, 0.0, 0.5),
|
||||
};
|
||||
|
||||
let percent = timing_point.time.as_seconds() / len;
|
||||
let x = BOUNDS.x + percent as f32 * BOUNDS.w;
|
||||
|
||||
let line = Mesh::new_line(
|
||||
ctx,
|
||||
&[
|
||||
Point2::new(x, BOUNDS.y),
|
||||
Point2::new(x, BOUNDS.y + BOUNDS.h),
|
||||
],
|
||||
1.0,
|
||||
color,
|
||||
)?;
|
||||
graphics::draw(ctx, &line, DrawParam::default())?;
|
||||
}
|
||||
|
||||
let percent = song.position()? / len;
|
||||
let x = BOUNDS.x + percent as f32 * BOUNDS.w;
|
||||
let line = Mesh::new_line(
|
||||
ctx,
|
||||
|
|
Loading…
Reference in a new issue