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