use better_default::Default;
use bevy::{asset::AssetLoader, platform::collections::HashMap, prelude::*};
use std::time::Duration;
mod parser;
#[allow(missing_docs)]
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, Hash)]
pub enum Direction {
Left,
Right,
Top,
Bottom,
}
#[allow(missing_docs)]
#[derive(Clone, Debug, serde::Deserialize, Eq, PartialEq, Hash)]
pub enum SpriteState {
Idle { direction: Direction },
Walk { direction: Direction },
Run { direction: Direction },
}
impl SpriteState {
pub fn change_direction(&self, direction: Direction) -> Self {
match self {
SpriteState::Idle { .. } => SpriteState::Idle { direction },
SpriteState::Walk { .. } => SpriteState::Walk { direction },
SpriteState::Run { .. } => SpriteState::Run { direction },
}
}
pub fn to_idle(&self) -> Self {
match self {
SpriteState::Idle { direction }
| SpriteState::Walk { direction }
| SpriteState::Run { direction } => SpriteState::Idle {
direction: direction.to_owned(),
},
}
}
pub fn to_walk(&self) -> Self {
match self {
SpriteState::Idle { direction }
| SpriteState::Walk { direction }
| SpriteState::Run { direction } => SpriteState::Walk {
direction: direction.to_owned(),
},
}
}
pub fn to_run(&self) -> Self {
match self {
SpriteState::Idle { direction }
| SpriteState::Walk { direction }
| SpriteState::Run { direction } => SpriteState::Run {
direction: direction.to_owned(),
},
}
}
}
#[derive(Debug, Default, Asset, TypePath, serde::Deserialize)]
pub struct Sheet {
#[default(Duration::from_secs(1))]
pub(super) animation: Duration,
default_indices: Vec<usize>,
mappings: HashMap<SpriteState, Vec<usize>>,
}
impl Sheet {
pub(crate) fn new(
animation: Duration,
default_indices: Vec<usize>,
mappings: HashMap<SpriteState, Vec<usize>>,
) -> Self {
Sheet {
animation,
default_indices,
mappings,
}
}
pub(crate) fn get(&self, state: &SpriteState) -> &Vec<usize> {
self.mappings.get(state).unwrap_or(&self.default_indices)
}
}
#[derive(Debug, Default, TypePath)]
pub(super) struct SheetLoader;
impl AssetLoader for SheetLoader {
type Asset = Sheet;
type Settings = ();
type Error = crate::error::Error;
async fn load(
&self,
reader: &mut dyn bevy::asset::io::Reader,
_: &Self::Settings,
_load_context: &mut bevy::asset::LoadContext<'_>,
) -> Result<Self::Asset, Self::Error> {
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes).await?;
parser::parse(std::str::from_utf8(&bytes)?)
}
fn extensions(&self) -> &[&str] {
&["sheet"]
}
}