add some initial timeline drawing code

This commit is contained in:
Michael Zhang 2021-01-08 14:55:33 -06:00
parent 399d80d72c
commit 00d640bdcf
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B

View file

@ -6,6 +6,7 @@ use std::path::Path;
use anyhow::Result;
use ggez::{
event::{EventHandler, KeyCode, KeyMods},
nalgebra::Point2,
graphics::{
self, Color, DrawMode, DrawParam, FillOptions, FilterMode, Mesh, Rect, StrokeOptions, Text,
WHITE,
@ -81,6 +82,7 @@ impl Game {
// 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);
const TIMELINE_BOUNDS: Rect = Rect::new(0.0, 0.0, 1024.0, 108.0);
graphics::clear(ctx, [0.0, 0.0, 0.0, 1.0].into());
@ -103,11 +105,64 @@ impl Game {
end_time: f64,
}
let mut visible_hitobjects = Vec::new();
let timeline_span = 6.0 / self.beatmap.timeline_zoom;
let timeline_left = time - timeline_span / 2.0;
let timeline_right = time + timeline_span / 2.0;
println!("left {:.3} right {:.3}", timeline_left, timeline_right);
let timeline_current_line_x = TIMELINE_BOUNDS.x + TIMELINE_BOUNDS.w * 0.5;
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,
),
],
2.0,
graphics::WHITE,
)?;
graphics::draw(ctx, &current_line, DrawParam::default())?;
let mut playfield_hitobjects = Vec::new();
let preempt = (self.beatmap.difficulty.approach_preempt() as f64) / 1000.0;
let fade_in = (self.beatmap.difficulty.approach_fade_time() as f64) / 1000.0;
for ho in self.beatmap.hit_objects.iter() {
// TODO: tighten this loop even more by binary searching for the start of the timeline and
// playfield hitobjects rather than looping through the entire beatmap, better yet, just
// keeping track of the old index will probably be much faster
for ho in self.beatmap.hit_objects.iter().rev() {
let ho_time = (ho.start_time.0 as f64) / 1000.0;
// draw in timeline
if ho_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;
println!(
" - [{}] {:.3}-{:.3} : {:.3}%",
self.beatmap.timeline_zoom,
timeline_left,
timeline_right,
timeline_percent * 100.0
);
self.skin.hitcircle.draw(
ctx,
(TIMELINE_BOUNDS.h, TIMELINE_BOUNDS.h),
DrawParam::default()
.dest([timeline_x, timeline_y + TIMELINE_BOUNDS.h / 2.0])
.offset([0.5, 0.0]),
)?;
self.skin.hitcircleoverlay.draw(
ctx,
(TIMELINE_BOUNDS.h, TIMELINE_BOUNDS.h),
DrawParam::default()
.dest([timeline_x, timeline_y + TIMELINE_BOUNDS.h / 2.0])
.offset([0.5, 0.0]),
)?;
}
// draw hitobject in playfield
let end_time;
let opacity = if time > ho_time - fade_in {
1.0
@ -126,7 +181,7 @@ impl Game {
}) => end_time = (spinner_end.0 as f64) / 1000.0,
};
if ho_time - preempt < time && time < end_time {
visible_hitobjects.push(DrawInfo {
playfield_hitobjects.push(DrawInfo {
hit_object: ho,
opacity,
end_time,
@ -140,7 +195,7 @@ impl Game {
let cs_osupx = self.beatmap.difficulty.circle_size_osupx();
let cs_real = cs_osupx * cs_scale;
for draw_info in visible_hitobjects.iter().rev() {
for draw_info in playfield_hitobjects.iter() {
let ho = draw_info.hit_object;
let ho_time = (ho.start_time.0 as f64) / 1000.0;
let pos = [
@ -184,15 +239,6 @@ impl Game {
DrawParam::default().dest(ball_pos),
(travel_percent / 0.25) as usize,
)?;
// let ball = Mesh::new_circle(
// ctx,
// DrawMode::Fill(FillOptions::default()),
// ball_pos,
// cs_real,
// 1.0,
// graphics::WHITE,
// )?;
// graphics::draw(ctx, &ball, DrawParam::default())?;
}
}