use std::{fmt, rc::Rc};
use crate::engine::d2::display::{ImageSprite, Sprite, Texture};
use super::Symbol;
#[derive(Default, Clone, Debug)]
pub struct Flipbook {
pub name: String,
pub frames: Vec<FlipbookFrame>,
}
impl Flipbook {
pub fn new<A: Texture + 'static>(name: String, textures: Vec<Rc<A>>) -> Self {
let mut instance = Self {
name,
frames: Vec::new(),
};
let duration_per_frame = 1.0 / textures.len() as f32;
for texture in textures {
instance.frames.push(FlipbookFrame::new(
(texture as Rc<dyn Texture>).clone(),
duration_per_frame,
));
}
instance
}
pub fn set_duration(&mut self, duration: f32) -> &Self {
let duration_per_frame = duration / self.frames.len() as f32;
for frame in self.frames.iter_mut() {
frame.duration = duration_per_frame;
}
self
}
pub fn set_anchor(&mut self, x: f32, y: f32) -> &Self {
for frame in self.frames.iter_mut() {
frame.anchor_x = x;
frame.anchor_y = y;
}
self
}
}
#[derive(Clone, Debug)]
pub struct FlipbookFrame {
pub texture: Rc<dyn Texture>,
pub duration: f32,
pub anchor_x: f32,
pub anchor_y: f32,
pub label: Option<String>,
}
impl FlipbookFrame {
fn new(texture: Rc<dyn Texture>, duration: f32) -> Self {
Self {
texture,
duration,
anchor_x: 0.0,
anchor_y: 0.0,
label: None,
}
}
fn to_symbol(&self) -> FrameSymbol {
FrameSymbol::new(self)
}
}
pub struct FrameSymbol {
pub name: String,
texture: Rc<dyn Texture>,
anchor_x: f32,
anchor_y: f32,
}
impl FrameSymbol {
pub fn new(frame: &FlipbookFrame) -> Self {
Self {
texture: frame.texture.clone(),
anchor_x: frame.anchor_x,
anchor_y: frame.anchor_y,
name: String::new(),
}
}
}
impl Symbol<ImageSprite> for FrameSymbol {
fn name(&self) -> Option<String> {
None
}
fn create_sprite(&self) -> ImageSprite {
let mut sprite = ImageSprite::new(Some(self.texture.clone()));
sprite.inner.set_anchor(self.anchor_x, self.anchor_y);
sprite
}
}
impl fmt::Debug for FrameSymbol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FrameSymbol")
.finish()
}
}