implement scrolling using arrow keys

This commit is contained in:
Michael Zhang 2021-01-10 01:37:15 -06:00
parent 7060f21188
commit f244d62a88
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
4 changed files with 74 additions and 7 deletions

2
Cargo.lock generated
View file

@ -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",

View file

@ -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"

View file

@ -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 {

View file

@ -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,