Skip to content
Snippets Groups Projects
Verified Commit bbd74a34 authored by Louis's avatar Louis :fire:
Browse files

Update compoennts and systems to use Bevy 15

parent 60978847
No related branches found
No related tags found
No related merge requests found
use bevy::prelude::*; use bevy::prelude::*;
use bevy::render::camera::ScalingMode; use bevy::render::camera::ScalingMode;
use micro_banimate::definitions::{AnimationSet, AnimationStatus, DirectionalAnimationBundle}; use micro_banimate::definitions::{create_directional_animation, AnimationSet, AnimationStatus};
use micro_banimate::directionality::{Directionality, Horizontal}; use micro_banimate::directionality::{Directionality, Horizontal};
fn main() { fn main() {
...@@ -48,23 +48,20 @@ fn spawn_assets(mut commands: Commands, assets: Res<ExampleAssets>) { ...@@ -48,23 +48,20 @@ fn spawn_assets(mut commands: Commands, assets: Res<ExampleAssets>) {
const HEIGHT: f32 = 320.0; const HEIGHT: f32 = 320.0;
commands.spawn(( commands.spawn((
TextureAtlas { Sprite::from_atlas_image(
layout: assets.atlas.clone_weak(), assets.sprites.clone_weak(),
index: 0, TextureAtlas {
}, layout: assets.atlas.clone_weak(),
SpriteBundle { index: 0,
texture: assets.sprites.clone_weak(), },
..Default::default()
},
DirectionalAnimationBundle::with_direction(
"idle",
assets.animations.clone_weak(),
Directionality::Right,
), ),
create_directional_animation(assets.animations.clone_weak(), "idle"),
Directionality::Right,
)); ));
commands.spawn(Camera2dBundle { commands.spawn((
projection: OrthographicProjection { Camera2d::default(),
OrthographicProjection {
area: Rect::new(-(WIDTH / 2.0), -(HEIGHT / 2.0), WIDTH / 2.0, HEIGHT / 2.0), area: Rect::new(-(WIDTH / 2.0), -(HEIGHT / 2.0), WIDTH / 2.0, HEIGHT / 2.0),
scaling_mode: ScalingMode::AutoMin { scaling_mode: ScalingMode::AutoMin {
min_height: HEIGHT, min_height: HEIGHT,
...@@ -72,10 +69,9 @@ fn spawn_assets(mut commands: Commands, assets: Res<ExampleAssets>) { ...@@ -72,10 +69,9 @@ fn spawn_assets(mut commands: Commands, assets: Res<ExampleAssets>) {
}, },
far: 1000., far: 1000.,
near: -1000., near: -1000.,
..Default::default() ..OrthographicProjection::default_2d()
}, },
..Default::default() ));
});
} }
fn process_input( fn process_input(
......
...@@ -27,6 +27,9 @@ impl AnimationFrames { ...@@ -27,6 +27,9 @@ impl AnimationFrames {
)] )]
pub struct AnimationSet(pub HashMap<String, AnimationFrames>); pub struct AnimationSet(pub HashMap<String, AnimationFrames>);
#[derive(Clone, Debug, Component, PartialEq, Default, Deref, DerefMut)]
pub struct AnimationHandle(pub Handle<AnimationSet>);
#[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Default)] #[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SyncToParent; pub struct SyncToParent;
...@@ -59,7 +62,7 @@ pub enum AnimationMode { ...@@ -59,7 +62,7 @@ pub enum AnimationMode {
}, },
} }
#[derive(Clone, Debug, Component, PartialEq, PartialOrd, Default)] #[derive(Clone, Debug, Component, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct AnimationStatus { pub struct AnimationStatus {
pub active_name: String, pub active_name: String,
...@@ -67,6 +70,16 @@ pub struct AnimationStatus { ...@@ -67,6 +70,16 @@ pub struct AnimationStatus {
pub frame_time: f32, pub frame_time: f32,
} }
impl Default for AnimationStatus {
fn default() -> Self {
Self {
active_name: String::from("idle"),
active_step: 0,
frame_time: 0.0,
}
}
}
impl From<String> for AnimationStatus { impl From<String> for AnimationStatus {
fn from(value: String) -> Self { fn from(value: String) -> Self {
AnimationStatus { AnimationStatus {
...@@ -78,6 +91,13 @@ impl From<String> for AnimationStatus { ...@@ -78,6 +91,13 @@ impl From<String> for AnimationStatus {
} }
impl AnimationStatus { impl AnimationStatus {
pub fn new(name: impl ToString) -> Self {
AnimationStatus {
active_name: name.to_string(),
active_step: 0,
frame_time: 0.0,
}
}
pub fn set_animation(&mut self, name: impl ToString) { pub fn set_animation(&mut self, name: impl ToString) {
self.active_name = name.to_string(); self.active_name = name.to_string();
} }
...@@ -94,64 +114,44 @@ impl AnimationStatus { ...@@ -94,64 +114,44 @@ impl AnimationStatus {
} }
} }
#[derive(Clone, Debug, Bundle, Default)] #[derive(Component)]
pub struct DirectionalAnimationBundle { #[require(AnimationHandle, AnimationStatus, AnimationMode, Sprite)]
pub animation_handle: Handle<AnimationSet>, pub struct SpriteAnimation;
pub mode: AnimationMode, pub fn create_sprite_animation(
pub status: AnimationStatus, handle: Handle<AnimationSet>,
pub direction: Directionality, initial_anim: impl ToString,
} ) -> impl Bundle {
(
impl DirectionalAnimationBundle { SpriteAnimation,
pub fn new(initial_anim: impl ToString, handle: Handle<AnimationSet>) -> Self { AnimationHandle(handle),
Self { AnimationStatus::new(initial_anim),
animation_handle: handle, )
status: AnimationStatus { }
active_name: initial_anim.to_string(),
active_step: 0, #[derive(Component)]
frame_time: 0.0, #[require(
}, AnimationHandle,
mode: AnimationMode::Loop, AnimationStatus,
direction: Directionality::default(), AnimationMode,
} Directionality,
} Sprite
pub fn with_direction( )]
initial_anim: impl ToString, pub struct DirectionalAnimation;
handle: Handle<AnimationSet>, pub fn create_directional_animation(
direction: Directionality, handle: Handle<AnimationSet>,
) -> Self { initial_anim: impl ToString,
Self { ) -> impl Bundle {
animation_handle: handle, (
status: AnimationStatus { DirectionalAnimation,
active_name: initial_anim.to_string(), AnimationHandle(handle),
active_step: 0, AnimationStatus::new(initial_anim),
frame_time: 0.0, )
}, }
mode: AnimationMode::Loop, #[derive(Component)]
direction, #[require(Sprite, SyncToParent)]
} pub struct ChildAnimation;
} pub fn create_child_animation() -> impl Bundle {
} (ChildAnimation,)
#[derive(Clone, Debug, Bundle, Default)]
pub struct SpriteAnimationBundle {
pub animation_handle: Handle<AnimationSet>,
pub mode: AnimationMode,
pub status: AnimationStatus,
}
impl SpriteAnimationBundle {
pub fn new(initial_anim: impl ToString, handle: Handle<AnimationSet>) -> Self {
Self {
animation_handle: handle,
status: AnimationStatus {
active_name: initial_anim.to_string(),
active_step: 0,
frame_time: 0.0,
},
mode: AnimationMode::Loop,
}
}
} }
#[derive(Clone, Debug, Component, PartialEq, PartialOrd, Default, Deref, DerefMut)] #[derive(Clone, Debug, Component, PartialEq, PartialOrd, Default, Deref, DerefMut)]
...@@ -160,6 +160,7 @@ impl SpriteAnimationBundle { ...@@ -160,6 +160,7 @@ impl SpriteAnimationBundle {
derive(serde::Serialize, serde::Deserialize), derive(serde::Serialize, serde::Deserialize),
serde(transparent) serde(transparent)
)] )]
#[require(SimpleAnimationStatus)]
pub struct SimpleAnimation(pub AnimationFrames); pub struct SimpleAnimation(pub AnimationFrames);
impl From<AnimationFrames> for SimpleAnimation { impl From<AnimationFrames> for SimpleAnimation {
fn from(value: AnimationFrames) -> Self { fn from(value: AnimationFrames) -> Self {
...@@ -174,21 +175,9 @@ pub struct SimpleAnimationStatus { ...@@ -174,21 +175,9 @@ pub struct SimpleAnimationStatus {
pub frame_time: f32, pub frame_time: f32,
} }
#[derive(Clone, Debug, Bundle, PartialEq, PartialOrd, Default)] impl SimpleAnimation {
pub struct SimpleAnimationBundle {
pub anim: SimpleAnimation,
pub status: SimpleAnimationStatus,
}
impl SimpleAnimationBundle {
pub fn new(frames: Vec<usize>, frame_secs: f32) -> Self { pub fn new(frames: Vec<usize>, frame_secs: f32) -> Self {
SimpleAnimationBundle { AnimationFrames { frames, frame_secs }.into()
anim: AnimationFrames { frames, frame_secs }.into(),
status: SimpleAnimationStatus {
active_step: 0,
frame_time: 0.0,
},
}
} }
} }
...@@ -202,6 +191,7 @@ pub struct OverrideData(pub u128); ...@@ -202,6 +191,7 @@ pub struct OverrideData(pub u128);
derive(serde::Serialize, serde::Deserialize), derive(serde::Serialize, serde::Deserialize),
serde(transparent) serde(transparent)
)] )]
#[require(OverrideData)]
pub struct AnimationOverride(pub AnimationStatus); pub struct AnimationOverride(pub AnimationStatus);
impl AnimationOverride { impl AnimationOverride {
...@@ -234,8 +224,3 @@ impl AnimationOverrideBundle { ...@@ -234,8 +224,3 @@ impl AnimationOverrideBundle {
} }
} }
} }
#[derive(Clone, Debug, Bundle, Default)]
pub struct ChildAnimationBundle {
marker: SyncToParent,
}
...@@ -27,7 +27,7 @@ impl Error for LoaderError {} ...@@ -27,7 +27,7 @@ impl Error for LoaderError {}
#[cfg(feature = "json_loader")] #[cfg(feature = "json_loader")]
mod json_loader { mod json_loader {
use bevy::asset::io::Reader; use bevy::asset::io::Reader;
use bevy::asset::{AssetLoader, AsyncReadExt, LoadContext}; use bevy::asset::{AssetLoader, LoadContext};
use crate::definitions::AnimationSet; use crate::definitions::AnimationSet;
use crate::loader::LoaderError; use crate::loader::LoaderError;
...@@ -38,11 +38,11 @@ mod json_loader { ...@@ -38,11 +38,11 @@ mod json_loader {
type Settings = (); type Settings = ();
type Error = LoaderError; type Error = LoaderError;
async fn load<'a>( async fn load(
&'a self, &self,
reader: &'a mut Reader<'_>, reader: &mut dyn Reader,
_settings: &'a Self::Settings, _settings: &Self::Settings,
_load_context: &'a mut LoadContext<'_>, _load_context: &mut LoadContext<'_>,
) -> Result<Self::Asset, Self::Error> { ) -> Result<Self::Asset, Self::Error> {
let mut bytes = Vec::new(); let mut bytes = Vec::new();
reader reader
...@@ -74,11 +74,11 @@ mod toml_loader { ...@@ -74,11 +74,11 @@ mod toml_loader {
type Settings = (); type Settings = ();
type Error = LoaderError; type Error = LoaderError;
async fn load<'a>( async fn load(
&'a self, &self,
reader: &'a mut Reader<'_>, reader: &mut dyn Reader,
_settings: &'a Self::Settings, _settings: &Self::Settings,
_load_context: &'a mut LoadContext<'_>, _load_context: &mut LoadContext<'_>,
) -> Result<Self::Asset, Self::Error> { ) -> Result<Self::Asset, Self::Error> {
let mut bytes = String::new(); let mut bytes = String::new();
reader reader
......
use crate::definitions::{ use crate::definitions::{
AnimationOverride, AnimationPaused, AnimationSet, AnimationStatus, OverrideData, AnimationHandle, AnimationOverride, AnimationPaused, AnimationSet, AnimationStatus,
SimpleAnimation, SimpleAnimationStatus, SyncToParent, OverrideData, SimpleAnimation, SimpleAnimationStatus, SyncToParent,
}; };
use crate::directionality::Directionality; use crate::directionality::Directionality;
use crate::systems::AnimationCompleted; use crate::systems::AnimationCompleted;
use bevy::asset::Assets; use bevy::asset::Assets;
use bevy::ecs::query::{QueryData, QueryFilter}; use bevy::ecs::query::{QueryData, QueryFilter};
use bevy::prelude::{ use bevy::prelude::{Commands, Entity, EventWriter, Parent, Query, Res, Time, With, Without};
Commands, Entity, EventWriter, Handle, Parent, Query, Res, Time, With, Without, use bevy::sprite::Sprite;
};
use bevy::sprite::TextureAtlas;
#[derive(QueryData)] #[derive(QueryData)]
#[query_data(mutable)] #[query_data(mutable)]
pub struct AnimationComponents { pub struct AnimationComponents {
handle: &'static Handle<AnimationSet>, handle: &'static AnimationHandle,
status: &'static mut AnimationStatus, status: &'static mut AnimationStatus,
atlas: &'static mut TextureAtlas, sprite: &'static mut Sprite,
} }
#[derive(QueryData)] #[derive(QueryData)]
#[query_data(mutable)] #[query_data(mutable)]
pub struct DirectionalAnimationComponents { pub struct DirectionalAnimationComponents {
handle: &'static Handle<AnimationSet>, handle: &'static AnimationHandle,
direction: &'static Directionality, direction: &'static Directionality,
status: &'static mut AnimationStatus, status: &'static mut AnimationStatus,
atlas: &'static mut TextureAtlas, sprite: &'static mut Sprite,
} }
#[derive(QueryData)] #[derive(QueryData)]
#[query_data(mutable)] #[query_data(mutable)]
pub struct OverrideAnimationComponents { pub struct OverrideAnimationComponents {
handle: &'static Handle<AnimationSet>, handle: &'static AnimationHandle,
data: Option<&'static OverrideData>, data: Option<&'static OverrideData>,
status: &'static mut AnimationOverride, status: &'static mut AnimationOverride,
atlas: &'static mut TextureAtlas, sprite: &'static mut Sprite,
} }
#[derive(QueryData)] #[derive(QueryData)]
#[query_data(mutable)] #[query_data(mutable)]
pub struct DirectionalOverrideAnimationComponents { pub struct DirectionalOverrideAnimationComponents {
handle: &'static Handle<AnimationSet>, handle: &'static AnimationHandle,
direction: &'static Directionality, direction: &'static Directionality,
data: Option<&'static OverrideData>, data: Option<&'static OverrideData>,
status: &'static mut AnimationOverride, status: &'static mut AnimationOverride,
atlas: &'static mut TextureAtlas, sprite: &'static mut Sprite,
} }
#[derive(QueryData)] #[derive(QueryData)]
...@@ -52,7 +50,7 @@ pub struct DirectionalOverrideAnimationComponents { ...@@ -52,7 +50,7 @@ pub struct DirectionalOverrideAnimationComponents {
pub struct SimpleAnimationComponents { pub struct SimpleAnimationComponents {
anim: &'static SimpleAnimation, anim: &'static SimpleAnimation,
status: &'static mut SimpleAnimationStatus, status: &'static mut SimpleAnimationStatus,
atlas: &'static mut TextureAtlas, sprite: &'static mut Sprite,
} }
#[derive(QueryFilter)] #[derive(QueryFilter)]
pub struct OnlyAnimations { pub struct OnlyAnimations {
...@@ -83,7 +81,7 @@ pub struct OnlyDirectionalOverrideAnimations { ...@@ -83,7 +81,7 @@ pub struct OnlyDirectionalOverrideAnimations {
macro_rules! get_current_anim { macro_rules! get_current_anim {
($anims: expr, $handle: expr, $name: expr) => { ($anims: expr, $handle: expr, $name: expr) => {
match $anims.get($handle) { match $anims.get($handle.id()) {
Some(active) => match active.get(&$name) { Some(active) => match active.get(&$name) {
Some(inner) => inner, Some(inner) => inner,
None => continue, None => continue,
...@@ -92,7 +90,7 @@ macro_rules! get_current_anim { ...@@ -92,7 +90,7 @@ macro_rules! get_current_anim {
} }
}; };
($anims: expr, $handle: expr, $name: expr, $($also: expr),+) => { ($anims: expr, $handle: expr, $name: expr, $($also: expr),+) => {
match $anims.get($handle) { match $anims.get($handle.id()) {
Some(active) => match active.get(&$name)$(.or_else(|| active.get(&$also)))+ { Some(active) => match active.get(&$name)$(.or_else(|| active.get(&$also)))+ {
Some(inner) => inner, Some(inner) => inner,
None => continue, None => continue,
...@@ -103,27 +101,31 @@ macro_rules! get_current_anim { ...@@ -103,27 +101,31 @@ macro_rules! get_current_anim {
} }
macro_rules! tick_animation { macro_rules! tick_animation {
($delta: expr, $anim: expr, $status: expr, $atlas: expr) => {{ ($delta: expr, $anim: expr, $status: expr, $sprite: expr) => {{
let current_frame = $atlas.index; if let Some(atlas) = $sprite.texture_atlas.as_mut() {
let mut has_looped = false; let current_frame = atlas.index;
let mut has_looped = false;
$status.frame_time += $delta.as_secs_f32(); $status.frame_time += $delta.as_secs_f32();
while $status.frame_time >= $anim.frame_secs { while $status.frame_time >= $anim.frame_secs {
$status.frame_time = ($status.frame_time - $anim.frame_secs).max(0.0); $status.frame_time = ($status.frame_time - $anim.frame_secs).max(0.0);
let next_frame = $status.active_step.saturating_add(1); let next_frame = $status.active_step.saturating_add(1);
$status.active_step = if next_frame >= $anim.frames.len() { $status.active_step = if next_frame >= $anim.frames.len() {
has_looped = true; has_looped = true;
0 0
} else { } else {
next_frame next_frame
}; };
} }
if current_frame != $anim.frames[$status.active_step] { if current_frame != $anim.frames[$status.active_step] {
$atlas.index = $anim.frames[$status.active_step]; atlas.index = $anim.frames[$status.active_step];
} }
has_looped has_looped
} else {
false
}
}}; }};
} }
...@@ -136,11 +138,11 @@ pub fn play_animations( ...@@ -136,11 +138,11 @@ pub fn play_animations(
for AnimationComponentsItem { for AnimationComponentsItem {
mut status, mut status,
handle, handle,
mut atlas, mut sprite,
} in &mut anim_query } in &mut anim_query
{ {
let anim = get_current_anim!(animations, handle, status.active_name); let anim = get_current_anim!(animations, handle, status.active_name);
tick_animation!(delta, anim, status, atlas); tick_animation!(delta, anim, status, sprite);
} }
} }
...@@ -153,7 +155,7 @@ pub fn play_directional_animations( ...@@ -153,7 +155,7 @@ pub fn play_directional_animations(
for DirectionalAnimationComponentsItem { for DirectionalAnimationComponentsItem {
mut status, mut status,
handle, handle,
mut atlas, mut sprite,
direction, direction,
} in &mut anim_query } in &mut anim_query
{ {
...@@ -164,7 +166,7 @@ pub fn play_directional_animations( ...@@ -164,7 +166,7 @@ pub fn play_directional_animations(
status.active_name status.active_name
); );
tick_animation!(delta, anim, status, atlas); tick_animation!(delta, anim, status, sprite);
} }
} }
...@@ -181,13 +183,13 @@ pub fn play_override_animation( ...@@ -181,13 +183,13 @@ pub fn play_override_animation(
OverrideAnimationComponentsItem { OverrideAnimationComponentsItem {
mut status, mut status,
handle, handle,
mut atlas, mut sprite,
data, data,
}, },
) in &mut anim_query ) in &mut anim_query
{ {
let anim = get_current_anim!(animations, handle, status.active_name); let anim = get_current_anim!(animations, handle, status.active_name);
let looped = tick_animation!(delta, anim, status, atlas); let looped = tick_animation!(delta, anim, status, sprite);
if looped { if looped {
commands commands
.entity(entity) .entity(entity)
...@@ -220,7 +222,7 @@ pub fn play_directional_override_animation( ...@@ -220,7 +222,7 @@ pub fn play_directional_override_animation(
mut status, mut status,
direction, direction,
handle, handle,
mut atlas, mut sprite,
data, data,
}, },
) in &mut anim_query ) in &mut anim_query
...@@ -232,7 +234,7 @@ pub fn play_directional_override_animation( ...@@ -232,7 +234,7 @@ pub fn play_directional_override_animation(
status.active_name status.active_name
); );
let looped = tick_animation!(delta, anim, status, atlas); let looped = tick_animation!(delta, anim, status, sprite);
if looped { if looped {
commands commands
.entity(entity) .entity(entity)
...@@ -255,22 +257,33 @@ pub fn play_simple_animation( ...@@ -255,22 +257,33 @@ pub fn play_simple_animation(
let delta = time.delta(); let delta = time.delta();
for SimpleAnimationComponentsItem { for SimpleAnimationComponentsItem {
mut status, mut status,
mut atlas, mut sprite,
anim, anim,
} in &mut anim_query } in &mut anim_query
{ {
tick_animation!(delta, *anim, status, atlas); tick_animation!(delta, *anim, status, sprite);
} }
} }
pub fn sync_child_animation( pub fn sync_child_animation(
mut children: Query<(&Parent, &mut TextureAtlas), With<SyncToParent>>, mut children: Query<(&Parent, &mut Sprite), With<SyncToParent>>,
parents: Query<&TextureAtlas, Without<SyncToParent>>, parents: Query<&Sprite, Without<SyncToParent>>,
) { ) {
for (parent, mut child_sprite) in &mut children { for (parent, mut child_sprite) in &mut children {
if let Ok(parent_sprite) = parents.get(**parent) { if let Ok(parent_sprite) = parents.get(**parent) {
if parent_sprite.index != child_sprite.index { match (
child_sprite.index = parent_sprite.index; parent_sprite.texture_atlas.as_ref(),
child_sprite.texture_atlas.as_mut(),
) {
(Some(parent_value), Some(child_value)) => {
if child_value.index != parent_value.index {
*child_value = parent_value.clone();
}
}
(Some(parent_value), None) => {
child_sprite.texture_atlas = Some(parent_value.clone());
}
_ => {}
} }
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment