draw colors

This commit is contained in:
Michael Zhang 2021-01-08 18:45:09 -06:00
parent 5684670344
commit 0efe7582d3
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
3 changed files with 57 additions and 28 deletions

View file

@ -21,6 +21,21 @@ impl BeatmapExt {
BeatmapExt { inner, hit_objects } BeatmapExt { inner, hit_objects }
} }
pub fn compute_colors(&mut self) {
let mut color_idx = 0;
let mut number = 1;
for ho in self.hit_objects.iter_mut() {
if ho.inner.new_combo {
number = 1;
color_idx = (color_idx+1) % self.inner.colors.len();
}
ho.number = number;
ho.color_idx = color_idx;
number += 1;
}
}
pub fn compute_stacking(&mut self) { pub fn compute_stacking(&mut self) {
self.compute_stacking_inner(0, self.hit_objects.len() - 1) self.compute_stacking_inner(0, self.hit_objects.len() - 1)
} }

View file

@ -16,8 +16,8 @@ use ggez::{
use libosu::{Beatmap, HitObject, HitObjectKind, Point, SpinnerInfo, Spline}; use libosu::{Beatmap, HitObject, HitObjectKind, Point, SpinnerInfo, Spline};
use crate::audio::{AudioEngine, Sound}; use crate::audio::{AudioEngine, Sound};
use crate::hit_object::HitObjectExt;
use crate::beatmap::{BeatmapExt, STACK_DISTANCE}; use crate::beatmap::{BeatmapExt, STACK_DISTANCE};
use crate::hit_object::HitObjectExt;
use crate::skin::Skin; use crate::skin::Skin;
use crate::slider_render::render_slider; use crate::slider_render::render_slider;
@ -61,12 +61,13 @@ impl Game {
let beatmap = Beatmap::from_osz(&contents)?; let beatmap = Beatmap::from_osz(&contents)?;
self.beatmap = BeatmapExt::new(beatmap); self.beatmap = BeatmapExt::new(beatmap);
self.beatmap.compute_stacking(); self.beatmap.compute_colors();
// self.beatmap.compute_stacking();
let dir = path.parent().unwrap(); let dir = path.parent().unwrap();
let song = Sound::create(dir.join(&self.beatmap.inner.audio_filename))?; let song = Sound::create(dir.join(&self.beatmap.inner.audio_filename))?;
song.set_position(113.0)?; song.set_position(28.0)?;
self.song = Some(song); self.song = Some(song);
Ok(()) Ok(())
@ -107,12 +108,12 @@ impl Game {
hit_object: &'a HitObjectExt, hit_object: &'a HitObjectExt,
opacity: f64, opacity: f64,
end_time: f64, end_time: f64,
color: Color,
} }
let timeline_span = 6.0 / self.beatmap.inner.timeline_zoom; let timeline_span = 6.0 / self.beatmap.inner.timeline_zoom;
let timeline_left = time - timeline_span / 2.0; let timeline_left = time - timeline_span / 2.0;
let timeline_right = 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 timeline_current_line_x = TIMELINE_BOUNDS.x + TIMELINE_BOUNDS.w * 0.5;
let current_line = Mesh::new_line( let current_line = Mesh::new_line(
ctx, ctx,
@ -137,25 +138,26 @@ impl Game {
// keeping track of the old index will probably be much faster // keeping track of the old index will probably be much faster
for ho in self.beatmap.hit_objects.iter().rev() { for ho in self.beatmap.hit_objects.iter().rev() {
let ho_time = (ho.inner.start_time.0 as f64) / 1000.0; let ho_time = (ho.inner.start_time.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,
color.green as f32 / 256.0,
color.blue as f32 / 256.0,
1.0,
);
// draw in timeline // draw in timeline
if ho_time >= timeline_left && ho_time <= timeline_right { if ho_time >= timeline_left && ho_time <= timeline_right {
let timeline_percent = (ho_time - timeline_left) / (timeline_right - timeline_left); 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_x = timeline_percent as f32 * TIMELINE_BOUNDS.w + TIMELINE_BOUNDS.x;
let timeline_y = TIMELINE_BOUNDS.y; let timeline_y = TIMELINE_BOUNDS.y;
println!(
" - [{}] {:.3}-{:.3} : {:.3}%",
self.beatmap.inner.timeline_zoom,
timeline_left,
timeline_right,
timeline_percent * 100.0
);
self.skin.hitcircle.draw( self.skin.hitcircle.draw(
ctx, ctx,
(TIMELINE_BOUNDS.h, TIMELINE_BOUNDS.h), (TIMELINE_BOUNDS.h, TIMELINE_BOUNDS.h),
DrawParam::default() DrawParam::default()
.dest([timeline_x, timeline_y + TIMELINE_BOUNDS.h / 2.0]) .dest([timeline_x, timeline_y + TIMELINE_BOUNDS.h / 2.0])
.offset([0.5, 0.0]), .offset([0.5, 0.0])
.color(color),
)?; )?;
self.skin.hitcircleoverlay.draw( self.skin.hitcircleoverlay.draw(
ctx, ctx,
@ -189,6 +191,7 @@ impl Game {
hit_object: ho, hit_object: ho,
opacity, opacity,
end_time, end_time,
color,
}); });
} }
} }
@ -207,8 +210,9 @@ impl Game {
PLAYFIELD_BOUNDS.x + osupx_scale_x * ho.inner.pos.0 as f32 - stacking, PLAYFIELD_BOUNDS.x + osupx_scale_x * ho.inner.pos.0 as f32 - stacking,
PLAYFIELD_BOUNDS.y + osupx_scale_y * ho.inner.pos.1 as f32 - stacking, PLAYFIELD_BOUNDS.y + osupx_scale_y * ho.inner.pos.1 as f32 - stacking,
]; ];
let color = graphics::Color::new(1.0, 1.0, 1.0, draw_info.opacity as f32); let color = draw_info.color;
let mut slider_info = None;
if let HitObjectKind::Slider(info) = &ho.inner.kind { if let HitObjectKind::Slider(info) = &ho.inner.kind {
let color = graphics::Color::new(1.0, 1.0, 1.0, 0.6 * draw_info.opacity as f32); let color = graphics::Color::new(1.0, 1.0, 1.0, 0.6 * draw_info.opacity as f32);
let spline = render_slider( let spline = render_slider(
@ -219,7 +223,22 @@ impl Game {
&ho.inner, &ho.inner,
color, color,
)?; )?;
slider_info = Some((info, spline));
}
self.skin.hitcircle.draw(
ctx,
(cs_real * 2.0, cs_real * 2.0),
DrawParam::default().dest(pos).color(color),
)?;
self.skin.hitcircleoverlay.draw(
ctx,
(cs_real * 2.0, cs_real * 2.0),
DrawParam::default().dest(pos),
)?;
if let Some((info, spline)) = slider_info {
if time > ho_time && time < draw_info.end_time { if time > ho_time && time < draw_info.end_time {
let elapsed_time = time - ho_time; let elapsed_time = time - ho_time;
let total_duration = draw_info.end_time - ho_time; let total_duration = draw_info.end_time - ho_time;
@ -241,24 +260,12 @@ impl Game {
self.skin.sliderb.draw_frame( self.skin.sliderb.draw_frame(
ctx, ctx,
(cs_real * 2.0, cs_real * 2.0), (cs_real * 2.0, cs_real * 2.0),
DrawParam::default().dest(ball_pos), DrawParam::default().dest(ball_pos).color(color),
(travel_percent / 0.25) as usize, (travel_percent / 0.25) as usize,
)?; )?;
} }
} }
self.skin.hitcircle.draw(
ctx,
(cs_real * 2.0, cs_real * 2.0),
DrawParam::default().dest(pos).color(color),
)?;
self.skin.hitcircleoverlay.draw(
ctx,
(cs_real * 2.0, cs_real * 2.0),
DrawParam::default().dest(pos).color(color),
)?;
if time < ho_time { if time < ho_time {
let time_diff = ho_time - time; let time_diff = ho_time - time;
let approach_r = cs_real * (1.0 + 2.0 * time_diff as f32 / 0.75); let approach_r = cs_real * (1.0 + 2.0 * time_diff as f32 / 0.75);

View file

@ -1,12 +1,19 @@
use libosu::HitObject; use libosu::{Color, HitObject};
pub struct HitObjectExt { pub struct HitObjectExt {
pub inner: HitObject, pub inner: HitObject,
pub stacking: usize, pub stacking: usize,
pub number: usize,
pub color_idx: usize,
} }
impl HitObjectExt { impl HitObjectExt {
pub fn new(inner: HitObject) -> Self { pub fn new(inner: HitObject) -> Self {
HitObjectExt { inner, stacking: 0 } HitObjectExt {
inner,
stacking: 0,
number: 0,
color_idx: 0,
}
} }
} }