draw the background image

This commit is contained in:
Michael Zhang 2021-01-13 06:51:33 -06:00
parent 09d26a9022
commit 27859bc05a
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
8 changed files with 77 additions and 9 deletions

10
Cargo.lock generated
View file

@ -830,6 +830,7 @@ dependencies = [
"anyhow",
"bass-sys",
"ggez",
"image",
"libosu",
"log",
"num",
@ -1282,10 +1283,12 @@ dependencies = [
"byteorder",
"color_quant",
"gif",
"jpeg-decoder",
"num-iter",
"num-rational",
"num-traits",
"png",
"scoped_threadpool",
"tiff",
]
@ -1364,6 +1367,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc797adac5f083b8ff0ca6f6294a999393d76e197c36488e2ef732c4715f6fa3"
dependencies = [
"byteorder",
"rayon",
]
[[package]]
@ -2505,6 +2509,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
[[package]]
name = "scoped_threadpool"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
[[package]]
name = "scopeguard"
version = "1.1.0"

View file

@ -22,6 +22,7 @@ stderrlog = "0.5.1"
num = "0.3.1"
ordered-float = "2.0.1"
structopt = "0.3.21"
image = "0.23.12"
[dependencies.libosu]
git = "https://github.com/iptq/libosu"

View file

@ -1,10 +1,18 @@
use anyhow::Result;
use ggez::Context;
use ggez::{
graphics::{self, Color, DrawParam},
Context,
};
use super::Game;
impl Game {
pub(super) fn draw_background(&self, ctx: &mut Context) -> Result<()> {
if let Some(image) = &self.background_image {
let dim = Color::new(1.0, 1.0, 1.0, 0.35);
graphics::draw(ctx, image, DrawParam::default().color(dim))?;
}
Ok(())
}
}

View file

@ -12,10 +12,11 @@ use std::str::FromStr;
use anyhow::Result;
use ggez::{
event::{EventHandler, KeyCode, KeyMods},
graphics::{self, Color, DrawParam, FilterMode, Rect, Text, WHITE},
event::{EventHandler, KeyCode, KeyMods, MouseButton},
graphics::{self, Color, DrawParam, FilterMode, Image, Rect, Text, WHITE},
Context, GameError, GameResult,
};
use image::io::Reader as ImageReader;
use libosu::{
beatmap::Beatmap,
hitobject::{HitObjectKind, SpinnerInfo},
@ -28,6 +29,7 @@ use crate::audio::{AudioEngine, Sound};
use crate::beatmap::{BeatmapExt, STACK_DISTANCE};
use crate::hitobject::HitObjectExt;
use crate::skin::Skin;
use crate::utils;
pub const PLAYFIELD_BOUNDS: Rect = Rect::new(112.0, 122.0, 800.0, 600.0);
pub const DEFAULT_COLORS: &[(f32, f32, f32)] = &[
@ -48,6 +50,7 @@ pub struct Game {
frame: usize,
slider_cache: SliderCache,
combo_colors: Vec<Color>,
background_image: Option<Image>,
keymap: HashSet<KeyCode>,
current_uninherited_timing_point: Option<TimingPoint>,
@ -74,6 +77,7 @@ impl Game {
.iter()
.map(|(r, g, b)| Color::new(*r, *g, *b, 1.0))
.collect(),
background_image: None,
keymap: HashSet::new(),
current_uninherited_timing_point: None,
@ -81,7 +85,7 @@ impl Game {
})
}
pub fn load_beatmap(&mut self, path: impl AsRef<Path>) -> Result<()> {
pub fn load_beatmap(&mut self, ctx: &mut Context, path: impl AsRef<Path>) -> Result<()> {
let path = path.as_ref();
let mut file = File::open(&path)?;
@ -118,6 +122,25 @@ impl Game {
let dir = path.parent().unwrap();
// TODO: more background images possible?
for evt in self.beatmap.inner.events.iter() {
use libosu::events::Event;
if let Event::Background(evt) = evt {
let path = utils::fuck_you_windows(dir, &evt.filename)?;
if let Some(path) = path {
let img = ImageReader::open(path)?.decode()?;
let img_buf = img.into_rgba8();
let image = Image::from_rgba8(
ctx,
img_buf.width() as u16,
img_buf.height() as u16,
img_buf.as_raw(),
)?;
self.background_image = Some(image);
}
}
}
let song = Sound::create(dir.join(&self.beatmap.inner.audio_filename))?;
self.song = Some(song);
self.timestamp_changed()?;
@ -395,6 +418,8 @@ impl EventHandler for Game {
Ok(())
}
fn mouse_button_down_event(&mut self, ctx: &mut Context, _: MouseButton, x: f32, y: f32) {}
fn key_up_event(&mut self, _: &mut Context, keycode: KeyCode, _: KeyMods) {
use KeyCode::*;
match keycode {

View file

@ -189,7 +189,10 @@ impl Game {
.with_line_width(BOUNDS.h)
.with_line_cap(LineCap::Round),
),
&[Point2::from([head_x, body_y]), Point2::from([tail_x, body_y])],
&[
Point2::from([head_x, body_y]),
Point2::from([tail_x, body_y]),
],
color,
)?;
graphics::draw(ctx, &body, DrawParam::default())?;

View file

@ -12,6 +12,7 @@ mod beatmap;
mod game;
mod hitobject;
mod skin;
mod utils;
use std::path::PathBuf;
@ -55,7 +56,7 @@ fn main() -> Result<()> {
game.skin.load_all(&mut ctx)?;
if let Some(path) = opt.path {
game.load_beatmap(path)?;
game.load_beatmap(&mut ctx, path)?;
}
if let Some(start_time) = opt.start_time {

View file

@ -92,9 +92,7 @@ impl Texture {
graphics::draw(
ctx,
image,
param
.scale([x_scale, y_scale])
.offset([0.5, 0.5]),
param.scale([x_scale, y_scale]).offset([0.5, 0.5]),
)?;
Ok(())
}

22
src/utils.rs Normal file
View file

@ -0,0 +1,22 @@
use std::path::{Path, PathBuf};
use anyhow::Result;
pub fn fuck_you_windows(
parent: impl AsRef<Path>,
name: impl AsRef<str>,
) -> Result<Option<PathBuf>> {
let parent = parent.as_ref();
let name = name.as_ref();
let name_lower = name.to_ascii_lowercase();
for entry in parent.read_dir()? {
let entry = entry?;
let entry_lower = entry.file_name().to_str().unwrap().to_ascii_lowercase();
if name_lower == entry_lower {
return Ok(Some(entry.path()));
}
}
Ok(None)
}