93 lines
2.9 KiB
Rust
93 lines
2.9 KiB
Rust
use raylib::{core::color::Color, math::{Rectangle, Vector2}, prelude::{RaylibDraw, RaylibDrawHandle, RaylibMode2D}, texture::Texture2D};
|
|
|
|
/// A wrapper around an animation spritesheet
|
|
pub struct FrameAnimationWrapper {
|
|
pub sprite_sheet: Texture2D,
|
|
size: Vector2,
|
|
frame_count: u32,
|
|
frames_per_second: u8,
|
|
start_time_seconds: f64,
|
|
}
|
|
|
|
impl FrameAnimationWrapper {
|
|
|
|
/// Create a new animation from a texture containing all frames
|
|
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,
|
|
}
|
|
}
|
|
|
|
/// Start the animation
|
|
pub fn start(&mut self, handle: &RaylibDrawHandle) {
|
|
if self.start_time_seconds == 0.0 {
|
|
self.start_time_seconds = handle.get_time();
|
|
}
|
|
}
|
|
|
|
/// Stop (and reset) the animation
|
|
pub fn stop(&mut self) {
|
|
self.start_time_seconds = 0.0;
|
|
}
|
|
|
|
/// Get the index of the currently displayed frame
|
|
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;
|
|
}
|
|
|
|
/// Draw the next frame to the screen at `position`
|
|
pub fn draw(&mut self, handle: &mut RaylibMode2D<RaylibDrawHandle>, position: Vector2, rotation: f32) {
|
|
let frame_id = self.get_current_frame_id(handle);
|
|
self.draw_frame(handle, position, rotation, frame_id);
|
|
}
|
|
|
|
/// Draw a specified frame to the screen at `position`
|
|
pub fn draw_frame(
|
|
&mut self,
|
|
handle: &mut RaylibMode2D<RaylibDrawHandle>,
|
|
position: Vector2,
|
|
rotation: f32,
|
|
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,
|
|
};
|
|
let frame_dest = Rectangle {
|
|
x: position.x,
|
|
y: position.y,
|
|
width: self.size.x,
|
|
height: self.size.y,
|
|
};
|
|
|
|
// Rotation origin
|
|
let origin = Vector2 {
|
|
x: self.size.x / 2.0,
|
|
y: self.size.y / 2.0
|
|
};
|
|
|
|
// Render
|
|
handle.draw_texture_pro(&mut self.sprite_sheet, frame_box, frame_dest, origin, rotation, Color::WHITE);
|
|
}
|
|
}
|