draw ticks
This commit is contained in:
parent
448b8e4356
commit
300208e21a
4 changed files with 97 additions and 21 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -1037,8 +1037,8 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
|
|||
|
||||
[[package]]
|
||||
name = "libosu"
|
||||
version = "0.0.12"
|
||||
source = "git+https://github.com/iptq/libosu?rev=332b7a55559c0257cc4d39577240b1cab5ed3d07#332b7a55559c0257cc4d39577240b1cab5ed3d07"
|
||||
version = "0.0.13"
|
||||
source = "git+https://github.com/iptq/libosu?rev=dee4d05eeaba1313a17eefbbd7679a947b52fbc1#dee4d05eeaba1313a17eefbbd7679a947b52fbc1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags",
|
||||
|
|
|
@ -20,4 +20,4 @@ ordered-float = "2.0.1"
|
|||
|
||||
[dependencies.libosu]
|
||||
git = "https://github.com/iptq/libosu"
|
||||
rev = "332b7a55559c0257cc4d39577240b1cab5ed3d07"
|
||||
rev = "dee4d05eeaba1313a17eefbbd7679a947b52fbc1"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
mod timeline;
|
||||
mod sliders;
|
||||
mod timeline;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
|
@ -114,8 +114,6 @@ impl Game {
|
|||
color: Color,
|
||||
}
|
||||
|
||||
self.draw_timeline(ctx, time)?;
|
||||
|
||||
let mut playfield_hitobjects = Vec::new();
|
||||
let preempt = (self.beatmap.inner.difficulty.approach_preempt() as f64) / 1000.0;
|
||||
let fade_in = (self.beatmap.inner.difficulty.approach_fade_time() as f64) / 1000.0;
|
||||
|
@ -164,6 +162,8 @@ impl Game {
|
|||
}
|
||||
}
|
||||
|
||||
self.draw_timeline(ctx, time)?;
|
||||
|
||||
let cs_scale = PLAYFIELD_BOUNDS.w / 640.0;
|
||||
let osupx_scale_x = PLAYFIELD_BOUNDS.w / 512.0;
|
||||
let osupx_scale_y = PLAYFIELD_BOUNDS.h / 384.0;
|
||||
|
|
|
@ -1,34 +1,108 @@
|
|||
use anyhow::Result;
|
||||
use ggez::{
|
||||
graphics::{self, DrawParam, Mesh, Rect},
|
||||
graphics::{self, Color, DrawParam, Mesh, Rect, WHITE},
|
||||
nalgebra::Point2,
|
||||
Context,
|
||||
};
|
||||
use libosu::TimingPointKind;
|
||||
|
||||
use crate::hit_object::HitObjectExt;
|
||||
|
||||
use super::Game;
|
||||
|
||||
pub const TIMELINE_BOUNDS: Rect = Rect::new(0.0, 0.0, 1024.0, 108.0);
|
||||
pub const BOUNDS: Rect = Rect::new(0.0, 54.0, 768.0, 54.0);
|
||||
|
||||
pub const RED: Color = Color::new(1.0, 0.0, 0.0, 1.0);
|
||||
pub const BLUE: Color = Color::new(0.0, 0.0, 1.0, 1.0);
|
||||
pub const TICKS: &[&[(Color, f32)]] = &[
|
||||
&[],
|
||||
&[],
|
||||
&[],
|
||||
&[],
|
||||
&[(WHITE, 1.0), (BLUE, 0.5), (RED, 0.5), (BLUE, 0.5)],
|
||||
];
|
||||
|
||||
impl Game {
|
||||
pub(super) fn draw_timeline(&self, ctx: &mut Context, time: f64) -> Result<()> {
|
||||
let timeline_span = 6.0 / self.beatmap.inner.timeline_zoom;
|
||||
let timeline_current_line_x = TIMELINE_BOUNDS.x + TIMELINE_BOUNDS.w * 0.5;
|
||||
let timeline_left = time - timeline_span / 2.0;
|
||||
let timeline_right = time + timeline_span / 2.0;
|
||||
let timeline_current_line_x = BOUNDS.x + BOUNDS.w * 0.5;
|
||||
|
||||
// the vertical line
|
||||
let current_line = Mesh::new_line(
|
||||
ctx,
|
||||
&[
|
||||
Point2::new(timeline_current_line_x, TIMELINE_BOUNDS.y),
|
||||
Point2::new(
|
||||
timeline_current_line_x,
|
||||
TIMELINE_BOUNDS.y + TIMELINE_BOUNDS.h,
|
||||
),
|
||||
Point2::new(timeline_current_line_x, BOUNDS.y),
|
||||
Point2::new(timeline_current_line_x, BOUNDS.y + BOUNDS.h),
|
||||
],
|
||||
2.0,
|
||||
graphics::WHITE,
|
||||
)?;
|
||||
graphics::draw(ctx, ¤t_line, DrawParam::default())?;
|
||||
|
||||
// timing sections in this little span
|
||||
let mut last_uninherited = None;
|
||||
for timing_points in self.beatmap.inner.timing_points.windows(2) {
|
||||
let (fst, snd) = (&timing_points[0], &timing_points[1]);
|
||||
let fst_time = fst.time.as_seconds();
|
||||
let snd_time = snd.time.as_seconds();
|
||||
if let TimingPointKind::Uninherited(info) = &fst.kind {
|
||||
last_uninherited = Some(info);
|
||||
}
|
||||
|
||||
if let Some(last_uninherited) = last_uninherited {
|
||||
if (fst_time >= timeline_left && fst_time <= timeline_right)
|
||||
|| (snd_time >= timeline_left && snd_time <= timeline_right)
|
||||
|| (fst_time < timeline_left && snd_time > timeline_right)
|
||||
{
|
||||
// TODO: optimize this
|
||||
let mut time = fst.time.as_seconds();
|
||||
let beat = last_uninherited.mpb / 1000.0;
|
||||
let ticks = TICKS[last_uninherited.meter as usize];
|
||||
'outer: loop {
|
||||
for i in 0..last_uninherited.meter as usize {
|
||||
let tick_time = time + beat * i as f64 / last_uninherited.meter as f64;
|
||||
if tick_time > snd_time.min(timeline_right) {
|
||||
break 'outer;
|
||||
}
|
||||
|
||||
let (color, height) = ticks[i];
|
||||
let percent =
|
||||
(tick_time - timeline_left) / (timeline_right - timeline_left);
|
||||
let x = percent as f32 * BOUNDS.w + BOUNDS.x;
|
||||
let y2 = BOUNDS.y + BOUNDS.h;
|
||||
let y1 = y2 - BOUNDS.h * 0.3 * height;
|
||||
let tick = Mesh::new_line(
|
||||
ctx,
|
||||
&[Point2::new(x, y1), Point2::new(x, y2)],
|
||||
1.0,
|
||||
color,
|
||||
)?;
|
||||
graphics::draw(ctx, &tick, DrawParam::default())?;
|
||||
}
|
||||
time += beat;
|
||||
|
||||
if time >= snd_time.min(timeline_right) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// draw a bottom line for the timeline
|
||||
let bottom_line = Mesh::new_line(
|
||||
ctx,
|
||||
&[
|
||||
Point2::new(BOUNDS.x, BOUNDS.y + BOUNDS.h),
|
||||
Point2::new(BOUNDS.x + BOUNDS.w, BOUNDS.y + BOUNDS.h),
|
||||
],
|
||||
2.0,
|
||||
graphics::WHITE,
|
||||
)?;
|
||||
graphics::draw(ctx, &bottom_line, DrawParam::default())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -43,6 +117,8 @@ impl Game {
|
|||
let timeline_right = time + timeline_span / 2.0;
|
||||
|
||||
let ho_time = (ho.inner.start_time.0 as f64) / 1000.0;
|
||||
let end_time = (self.beatmap.inner.get_hitobject_end_time(&ho.inner).0 as f64) / 1000.0;
|
||||
|
||||
let color = self.beatmap.inner.colors[ho.color_idx];
|
||||
let color = graphics::Color::new(
|
||||
color.red as f32 / 256.0,
|
||||
|
@ -51,23 +127,23 @@ impl Game {
|
|||
1.0,
|
||||
);
|
||||
|
||||
if ho_time >= timeline_left && ho_time <= timeline_right {
|
||||
if end_time >= timeline_left && ho_time <= timeline_right {
|
||||
let timeline_percent = (ho_time - timeline_left) / (timeline_right - timeline_left);
|
||||
let timeline_x = timeline_percent as f32 * TIMELINE_BOUNDS.w + TIMELINE_BOUNDS.x;
|
||||
let timeline_y = TIMELINE_BOUNDS.y;
|
||||
let timeline_x = timeline_percent as f32 * BOUNDS.w + BOUNDS.x;
|
||||
let timeline_y = BOUNDS.y;
|
||||
self.skin.hitcircle.draw(
|
||||
ctx,
|
||||
(TIMELINE_BOUNDS.h, TIMELINE_BOUNDS.h),
|
||||
(BOUNDS.h, BOUNDS.h),
|
||||
DrawParam::default()
|
||||
.dest([timeline_x, timeline_y + TIMELINE_BOUNDS.h / 2.0])
|
||||
.dest([timeline_x, timeline_y + BOUNDS.h / 2.0])
|
||||
.offset([0.5, 0.0])
|
||||
.color(color),
|
||||
)?;
|
||||
self.skin.hitcircleoverlay.draw(
|
||||
ctx,
|
||||
(TIMELINE_BOUNDS.h, TIMELINE_BOUNDS.h),
|
||||
(BOUNDS.h, BOUNDS.h),
|
||||
DrawParam::default()
|
||||
.dest([timeline_x, timeline_y + TIMELINE_BOUNDS.h / 2.0])
|
||||
.dest([timeline_x, timeline_y + BOUNDS.h / 2.0])
|
||||
.offset([0.5, 0.0]),
|
||||
)?;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue