kinda implement numbers? they're still off tho

This commit is contained in:
Michael Zhang 2021-01-13 08:20:04 -06:00
parent 27859bc05a
commit a58c77a706
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
6 changed files with 156 additions and 14 deletions

2
run.sh
View file

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
export LD_LIBRARY_PATH=$(pwd)/bass-sys/linux/bass24/x64 export LD_LIBRARY_PATH=$(pwd)/bass-sys/linux/bass24/x64
echo $LD_LIBRARY_PATH echo $LD_LIBRARY_PATH
exec cargo run --release "$@" exec cargo run "$@"

View file

@ -8,9 +8,31 @@ use super::Game;
impl Game { impl Game {
pub(super) fn draw_background(&self, ctx: &mut Context) -> Result<()> { pub(super) fn draw_background(&self, ctx: &mut Context) -> Result<()> {
let screen_width = 1024;
let screen_height = 768;
let screen_ratio = screen_width as f32 / screen_height as f32;
if let Some(image) = &self.background_image { if let Some(image) = &self.background_image {
let dim = Color::new(1.0, 1.0, 1.0, 0.35); let dim = Color::new(1.0, 1.0, 1.0, 0.35);
graphics::draw(ctx, image, DrawParam::default().color(dim))?; let width = image.width();
let height = image.height();
let ratio = width as f32 / height as f32;
let scale =
// background is flatter than screen
if ratio < screen_ratio {
// take screen height
[screen_width as f32/width as f32,screen_height as f32/height as f32]
}
// background is more square than screen
else if ratio > screen_ratio {
[screen_width as f32/width as f32,screen_height as f32/height as f32]
}
// exactly the same ratio
else {
[screen_width as f32/width as f32,screen_height as f32/height as f32]
};
graphics::draw(ctx, image, DrawParam::default().color(dim).scale(scale))?;
} }
Ok(()) Ok(())

View file

@ -1,5 +1,6 @@
mod background; mod background;
mod grid; mod grid;
mod numbers;
mod seeker; mod seeker;
mod sliders; mod sliders;
mod timeline; mod timeline;
@ -262,7 +263,7 @@ impl Game {
&ho.inner, &ho.inner,
color, color,
)?; )?;
slider_info = Some((info, control_points, spline)); slider_info = Some((info, control_points));
let end_pos = ho.inner.end_pos().unwrap(); let end_pos = ho.inner.end_pos().unwrap();
let end_pos = [ let end_pos = [
@ -281,6 +282,7 @@ impl Game {
)?; )?;
} }
// draw main hitcircle
self.skin.hitcircle.draw( self.skin.hitcircle.draw(
ctx, ctx,
(cs_real * 2.0, cs_real * 2.0), (cs_real * 2.0, cs_real * 2.0),
@ -292,7 +294,11 @@ impl Game {
DrawParam::default().dest(pos), DrawParam::default().dest(pos),
)?; )?;
if let Some((info, control_points, spline)) = slider_info { // draw numbers
self.draw_numbers_on_circle(ctx, ho.number, pos, cs_real)?;
if let Some((info, control_points)) = slider_info {
let spline = self.slider_cache.get(&control_points).unwrap();
Game::render_slider_wireframe(ctx, &control_points, PLAYFIELD_BOUNDS)?; Game::render_slider_wireframe(ctx, &control_points, PLAYFIELD_BOUNDS)?;
if time > ho_time && time < draw_info.end_time { if time > ho_time && time < draw_info.end_time {

78
src/game/numbers.rs Normal file
View file

@ -0,0 +1,78 @@
use anyhow::Result;
use ggez::{
graphics::{self, DrawParam},
Context,
};
use super::Game;
impl Game {
pub(super) fn draw_numbers_on_circle(
&self,
ctx: &mut Context,
number: usize,
pos: [f32; 2],
cs: f32,
) -> Result<()> {
let number = number.to_string();
let digits = number.len();
let cs = cs / 1.5;
let mut digits = Vec::new();
let mut width = 0;
let mut first_height = None;
let spacing = 5;
for digit in number.chars() {
let texture = match digit {
'0' => &self.skin.default0,
'1' => &self.skin.default1,
'2' => &self.skin.default2,
'3' => &self.skin.default3,
'4' => &self.skin.default4,
'5' => &self.skin.default5,
'6' => &self.skin.default6,
'7' => &self.skin.default7,
'8' => &self.skin.default8,
'9' => &self.skin.default9,
_ => unreachable!(),
};
if let None = first_height {
first_height = Some(texture.height().unwrap());
}
let this_width = texture.width().unwrap();
width += this_width + spacing;
digits.push((digit, width, this_width, texture));
}
let height = first_height.unwrap();
let real_total_width = cs * width as f32 / height as f32;
let real_height = cs;
let left_off = pos[0]-real_total_width;
let real_y = pos[1];
for (_, x, w, digit) in digits {
let w = w as f32 / height as f32 * cs;
let real_x = left_off + x as f32 / width as f32 * real_total_width;
digit.draw(
ctx,
(w, real_height),
DrawParam::default().dest([real_x, real_y]),
)?;
}
// let pos = [leftmost + i as f32 / 2.0 * digit_width, pos[1]];
// let rect = graphics::Mesh::new_rectangle(
// ctx,
// graphics::DrawMode::Stroke(graphics::StrokeOptions::default()),
// [pos[0], pos[1], digit_width, cs].into(),
// [1.0, 0.0, 0.0, 1.0].into(),
// )?;
// graphics::draw(ctx, &rect, DrawParam::default().offset([0.5, 0.5]))?;
// texture.draw(
// ctx,
// (cs * 42.0 / 72.0, cs),
// DrawParam::default().offset([0.5, 0.5]).dest(pos),
// )?;
Ok(())
}
}

View file

@ -270,6 +270,14 @@ impl Game {
.dest([head_x, timeline_y + BOUNDS.h / 2.0]) .dest([head_x, timeline_y + BOUNDS.h / 2.0])
.offset([0.5, 0.0]), .offset([0.5, 0.0]),
)?; )?;
// draw numbers
self.draw_numbers_on_circle(
ctx,
ho.number,
[head_x, timeline_y + BOUNDS.h / 2.0],
BOUNDS.h / 2.0,
)?;
} }
Ok(()) Ok(())

View file

@ -1,3 +1,5 @@
use std::path::{Path, PathBuf};
use anyhow::Result; use anyhow::Result;
use ggez::{ use ggez::{
graphics::{self, DrawParam, Image}, graphics::{self, DrawParam, Image},
@ -5,7 +7,11 @@ use ggez::{
}; };
macro_rules! create_skin { macro_rules! create_skin {
($([$name:ident, $animatable:expr $(,)?]),* $(,)?) => { (
// regular skin textures
$( [$name:ident, $path:expr, $animatable:expr $(,)?]),*
$(,)?
) => {
pub struct Skin { pub struct Skin {
$( $(
pub $name: Texture, pub $name: Texture,
@ -15,7 +21,7 @@ macro_rules! create_skin {
impl Skin { impl Skin {
pub fn new() -> Self { pub fn new() -> Self {
Skin { Skin {
$($name: Texture::with_name(stringify!($name), $animatable),)* $($name: Texture::with_name(stringify!($name), $path, $animatable),)*
} }
} }
@ -31,30 +37,52 @@ macro_rules! create_skin {
} }
create_skin! { create_skin! {
[approachcircle, false], [approachcircle, "approachcircle", false],
[hitcircle, false], [hitcircle, "hitcircle", false],
[hitcircleoverlay, false], [hitcircleoverlay, "hitcircleoverlay", false],
[reversearrow, false], [reversearrow, "reversearrow", false],
[sliderb, true], [sliderb, "sliderb", true],
// TODO: actually read numbers from skin.ini
[default0, "default-0", false],
[default1, "default-1", false],
[default2, "default-2", false],
[default3, "default-3", false],
[default4, "default-4", false],
[default5, "default-5", false],
[default6, "default-6", false],
[default7, "default-7", false],
[default8, "default-8", false],
[default9, "default-9", false],
} }
pub struct Texture { pub struct Texture {
name: &'static str, name: &'static str,
path: &'static str,
image: Option<Image>, image: Option<Image>,
animatable: bool, animatable: bool,
animation: Vec<Image>, animation: Vec<Image>,
} }
impl Texture { impl Texture {
pub fn with_name(name: &'static str, animatable: bool) -> Self { pub fn with_name(name: &'static str, path: &'static str, animatable: bool) -> Self {
Texture { Texture {
name, name,
path,
image: None, image: None,
animatable, animatable,
animation: vec![], animation: vec![],
} }
} }
pub fn width(&self) -> Option<u16> {
self.image.as_ref().map(|image| image.width())
}
pub fn height(&self) -> Option<u16> {
self.image.as_ref().map(|image| image.height())
}
pub fn load(&mut self, ctx: &mut Context) -> Result<()> { pub fn load(&mut self, ctx: &mut Context) -> Result<()> {
let mut found = false; let mut found = false;
if self.animatable { if self.animatable {
@ -63,7 +91,7 @@ impl Texture {
self.animation.clear(); self.animation.clear();
let mut curr = 0; let mut curr = 0;
while let Ok(image) = Image::new(ctx, &format!("/{}{}{}.png", self.name, hyphen, curr)) while let Ok(image) = Image::new(ctx, &format!("/{}{}{}.png", self.path, hyphen, curr))
{ {
self.animation.push(image); self.animation.push(image);
found = true; found = true;
@ -73,7 +101,7 @@ impl Texture {
} }
if !found { if !found {
self.image = Some(Image::new(ctx, &format!("/{}.png", self.name))?); self.image = Some(Image::new(ctx, &format!("/{}.png", self.path))?);
} }
Ok(()) Ok(())