mirror of
https://github.com/Xevion/Pac-Man.git
synced 2025-12-10 00:07:52 -06:00
feat: atlas decoding & frame acquisition
This commit is contained in:
@@ -1,34 +1,24 @@
|
||||
//! This module provides a simple animation and atlas system for textures.
|
||||
use anyhow::Result;
|
||||
use glam::IVec2;
|
||||
use sdl2::{
|
||||
render::{Canvas, Texture},
|
||||
video::Window,
|
||||
};
|
||||
use sdl2::render::WindowCanvas;
|
||||
|
||||
use crate::entity::direction::Direction;
|
||||
use crate::texture::atlas::AtlasTexture;
|
||||
use crate::texture::FrameDrawn;
|
||||
use crate::texture::sprite::AtlasTile;
|
||||
|
||||
/// An animated texture using a texture atlas.
|
||||
pub struct AnimatedAtlasTexture {
|
||||
pub atlas: AtlasTexture,
|
||||
#[derive(Clone)]
|
||||
pub struct AnimatedTexture {
|
||||
pub frames: Vec<AtlasTile>,
|
||||
pub ticks_per_frame: u32,
|
||||
pub ticker: u32,
|
||||
pub reversed: bool,
|
||||
pub paused: bool,
|
||||
}
|
||||
|
||||
impl AnimatedAtlasTexture {
|
||||
pub fn new(
|
||||
texture: Texture<'static>,
|
||||
ticks_per_frame: u32,
|
||||
frame_count: u32,
|
||||
width: u32,
|
||||
height: u32,
|
||||
offset: Option<IVec2>,
|
||||
) -> Self {
|
||||
AnimatedAtlasTexture {
|
||||
atlas: AtlasTexture::new(texture, frame_count, width, height, offset),
|
||||
impl AnimatedTexture {
|
||||
pub fn new(frames: Vec<AtlasTile>, ticks_per_frame: u32) -> Self {
|
||||
AnimatedTexture {
|
||||
frames,
|
||||
ticks_per_frame,
|
||||
ticker: 0,
|
||||
reversed: false,
|
||||
@@ -36,38 +26,25 @@ impl AnimatedAtlasTexture {
|
||||
}
|
||||
}
|
||||
|
||||
fn current_frame(&self) -> u32 {
|
||||
self.ticker / self.ticks_per_frame
|
||||
}
|
||||
|
||||
/// Advances the animation by one tick, unless paused.
|
||||
pub fn tick(&mut self) {
|
||||
if self.paused {
|
||||
if self.paused || self.ticks_per_frame == 0 {
|
||||
return;
|
||||
}
|
||||
if self.reversed {
|
||||
if self.ticker > 0 {
|
||||
self.ticker -= 1;
|
||||
}
|
||||
if self.ticker == 0 {
|
||||
self.reversed = !self.reversed;
|
||||
}
|
||||
} else {
|
||||
self.ticker += 1;
|
||||
if self.ticker + 1 == self.ticks_per_frame * self.atlas.frame_count {
|
||||
self.reversed = !self.reversed;
|
||||
}
|
||||
|
||||
self.ticker += 1;
|
||||
}
|
||||
|
||||
pub fn current_tile(&self) -> &AtlasTile {
|
||||
if self.ticks_per_frame == 0 {
|
||||
return &self.frames[0];
|
||||
}
|
||||
let frame_index = (self.ticker / self.ticks_per_frame) as usize % self.frames.len();
|
||||
&self.frames[frame_index]
|
||||
}
|
||||
|
||||
pub fn set_color_modulation(&mut self, r: u8, g: u8, b: u8) {
|
||||
self.atlas.set_color_modulation(r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
impl FrameDrawn for AnimatedAtlasTexture {
|
||||
fn render(&self, canvas: &mut Canvas<Window>, position: IVec2, direction: Direction, frame: Option<u32>) {
|
||||
let frame = frame.unwrap_or_else(|| self.current_frame());
|
||||
self.atlas.render(canvas, position, direction, Some(frame));
|
||||
pub fn render(&self, canvas: &mut WindowCanvas, dest: sdl2::rect::Rect) -> Result<()> {
|
||||
let tile = self.current_tile();
|
||||
tile.render(canvas, dest)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user