diff --git a/assets/audio/distraction_dance.mp3 b/assets/audio/distraction_dance.mp3 new file mode 100644 index 0000000..a122cbf Binary files /dev/null and b/assets/audio/distraction_dance.mp3 differ diff --git a/assets/img/chr_henryStickman/flippycat.png b/assets/img/chr_henryStickman/flippycat.png new file mode 100644 index 0000000..9ae975c Binary files /dev/null and b/assets/img/chr_henryStickman/flippycat.png differ diff --git a/assets/img/chr_henryStickman/spritesheet.png b/assets/img/chr_henryStickman/spritesheet.png new file mode 100644 index 0000000..a399f48 Binary files /dev/null and b/assets/img/chr_henryStickman/spritesheet.png differ diff --git a/src/lib/animation/mod.rs b/src/lib/animation/mod.rs new file mode 100644 index 0000000..11c0c6d --- /dev/null +++ b/src/lib/animation/mod.rs @@ -0,0 +1 @@ +pub mod wrapper; \ No newline at end of file diff --git a/src/lib/animation/wrapper.rs b/src/lib/animation/wrapper.rs new file mode 100644 index 0000000..eb02da1 --- /dev/null +++ b/src/lib/animation/wrapper.rs @@ -0,0 +1,75 @@ +use raylib::{ + core::color::Color, + math::{Rectangle, Vector2}, + prelude::{RaylibDraw, RaylibDrawHandle}, + texture::Texture2D, +}; + +pub struct FrameAnimationWrapper { + sprite_sheet: Texture2D, + size: Vector2, + frame_count: u32, + frames_per_second: u8, + start_time_seconds: f64, +} + +impl FrameAnimationWrapper { + pub fn new(sprite_sheet: Texture2D, frame_size: Vector2, frame_count: u32, fps: u8) -> Self { + Self { + sprite_sheet, + size: frame_size, + frame_count, + frames_per_second: fps, + start_time_seconds: 0.0, + } + } + + pub fn start(&mut self, handle: &RaylibDrawHandle) { + self.start_time_seconds = handle.get_time(); + } + + pub fn stop(&mut self) { + self.start_time_seconds = 0.0; + } + + pub fn get_current_frame_id(&self, handle: &RaylibDrawHandle) -> u32 { + // Get the time since start + let time_since_start = handle.get_time() - self.start_time_seconds; + + // Determine the frame ID + return ((time_since_start * self.frames_per_second as f64) % self.frame_count as f64) + as u32; + } + + pub fn draw(&mut self, handle: &mut RaylibDrawHandle, position: Vector2) { + let frame_id = self.get_current_frame_id(handle); + self.draw_frame(handle, position, frame_id); + } + + pub fn draw_frame( + &mut self, + handle: &mut RaylibDrawHandle, + position: Vector2, + frame_number: u32, + ) { + // Determine the col number + let col = self.size.x * frame_number as f32; + + // Determine the row number + let frames_per_row = self.sprite_sheet.width as u32 / self.size.x as u32; + let row_number = frame_number / frames_per_row; + let row = row_number as f32 * self.size.y; + + // Build a relative bounding box for this single frame + let frame_box = Rectangle { + x: col, + y: row, + width: self.size.x, + height: self.size.y, + }; + println!("{:?}", frame_box); + // Render + // handle.draw_texture(&mut self.sprite_sheet, 0, 0, Color::WHITE); + handle.draw_texture_rec(&mut self.sprite_sheet, frame_box, position, Color::WHITE); + } +} diff --git a/src/lib/audio/mod.rs b/src/lib/audio/mod.rs new file mode 100644 index 0000000..11c0c6d --- /dev/null +++ b/src/lib/audio/mod.rs @@ -0,0 +1 @@ +pub mod wrapper; \ No newline at end of file diff --git a/src/lib/audio/wrapper.rs b/src/lib/audio/wrapper.rs new file mode 100644 index 0000000..ec2a159 --- /dev/null +++ b/src/lib/audio/wrapper.rs @@ -0,0 +1,31 @@ +use raylib::{audio::{Music, RaylibAudio}, prelude::RaylibDrawHandle}; + +pub struct AudioWrapper { + music: Music, +} + +impl AudioWrapper { + pub fn new(music: Music) -> Self { + Self { music } + } + + pub fn play(&mut self, audio_handle: &mut RaylibAudio) { + audio_handle.play_music_stream(&mut self.music); + } + + pub fn stop(&mut self, audio_handle: &mut RaylibAudio) { + audio_handle.stop_music_stream(&mut self.music); + } + + pub fn pause(&mut self, audio_handle: &mut RaylibAudio) { + audio_handle.pause_music_stream(&mut self.music); + } + + pub fn update(&mut self, audio_handle: &mut RaylibAudio) { + audio_handle.update_music_stream(&mut self.music); + } + + pub fn is_playing(&mut self, audio_handle: &mut RaylibAudio) -> bool { + return audio_handle.is_music_playing(&mut self.music); + } +} diff --git a/src/lib/mod.rs b/src/lib/mod.rs new file mode 100644 index 0000000..9af9ea2 --- /dev/null +++ b/src/lib/mod.rs @@ -0,0 +1,2 @@ +pub mod audio; +pub mod animation; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index e7a11a9..43372e6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,71 @@ +mod lib; + +use lib::{animation::wrapper::FrameAnimationWrapper, audio::wrapper::AudioWrapper}; +use raylib::prelude::*; + fn main() { - println!("Hello, world!"); + let (mut rl, thread) = raylib::init() + .size(800, 600) + .title("LDJam48 Tech Demo") + .build(); + rl.set_target_fps(120); + + // Set up audio + let mut audio = RaylibAudio::init_audio_device(); + let mut distraction_dance_sound = AudioWrapper::new( + Music::load_music_stream(&thread, "assets/audio/distraction_dance.mp3").unwrap(), + ); + + // Build an animation + let texture = + rl.load_texture(&thread, "assets/img/chr_henryStickman/spritesheet.png") + .unwrap(); + let mut stickman_animation = + FrameAnimationWrapper::new(texture, Vector2 { x: 472.0, y: 562.0 }, 44, 24); + + // State + let mut is_playing_dance = false; + + while !rl.window_should_close() { + let mut d = rl.begin_drawing(&thread); + + // Clear frame + d.clear_background(Color::WHITE); + + // Update the audio buffer + distraction_dance_sound.update(&mut audio); + + // Draw an animation frame + stickman_animation.draw(&mut d, Vector2 { x: 200.0, y: 0.0 }); + + // Begin the dance if needed + if !is_playing_dance { + // Play audio + distraction_dance_sound.play(&mut audio); + + // Play animation + stickman_animation.start(&d); + + is_playing_dance = true; + } + + // Reset the loop at the end of the track + if !distraction_dance_sound.is_playing(&mut audio) { + // Stop animation + stickman_animation.stop(); + + is_playing_dance = false; + } + + // Render debug info + d.draw_text("Tech Demo - do not redistribute", 10, 10, 20, Color::BLACK); + let fps = d.get_fps(); + d.draw_text(&format!("FPS: {}/120", fps), 10, 25, 20, Color::BLACK); + let spf = d.get_frame_time(); + d.draw_text(&format!("SPF: {}", spf), 10, 40, 20, Color::BLACK); + let dpi = d.get_window_scale_dpi(); + d.draw_text(&format!("DPI: {:?}", dpi), 10, 55, 20, Color::BLACK); + let frame = stickman_animation.get_current_frame_id(&d); + d.draw_text(&format!("Frame: {}", frame), 10, 70, 20, Color::BLACK); + } }