Wiring up animations (#47)
This commit is contained in:
127
src/animation.rs
Normal file
127
src/animation.rs
Normal file
@@ -0,0 +1,127 @@
|
||||
use crate::{
|
||||
GameState, character::CharacterAnimations, head::ActiveHead, heads_database::HeadsDatabase,
|
||||
};
|
||||
use bevy::{animation::RepeatAnimation, ecs::query::QueryData, prelude::*};
|
||||
use std::time::Duration;
|
||||
|
||||
pub fn plugin(app: &mut App) {
|
||||
app.register_type::<AnimationFlags>();
|
||||
|
||||
app.add_systems(
|
||||
Update,
|
||||
update_animation.run_if(in_state(GameState::Playing)),
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Component, Default, Reflect)]
|
||||
#[reflect(Component)]
|
||||
pub struct AnimationFlags {
|
||||
pub any_direction: bool,
|
||||
pub jumping: bool,
|
||||
pub just_jumped: bool,
|
||||
pub shooting: bool,
|
||||
pub hit: bool,
|
||||
}
|
||||
|
||||
#[derive(QueryData)]
|
||||
#[query_data(mutable)]
|
||||
pub struct AnimationController {
|
||||
pub transitions: &'static mut AnimationTransitions,
|
||||
pub player: &'static mut AnimationPlayer,
|
||||
}
|
||||
|
||||
impl AnimationController {
|
||||
pub fn play_inner(
|
||||
player: &mut AnimationPlayer,
|
||||
transitions: &mut AnimationTransitions,
|
||||
animation: AnimationNodeIndex,
|
||||
transition: Duration,
|
||||
repeat: RepeatAnimation,
|
||||
) {
|
||||
transitions
|
||||
.play(player, animation, transition)
|
||||
.set_repeat(repeat);
|
||||
}
|
||||
}
|
||||
|
||||
impl AnimationControllerItem<'_> {
|
||||
pub fn play(
|
||||
&mut self,
|
||||
animation: AnimationNodeIndex,
|
||||
transition: Duration,
|
||||
repeat: RepeatAnimation,
|
||||
) {
|
||||
AnimationController::play_inner(
|
||||
&mut self.player,
|
||||
&mut self.transitions,
|
||||
animation,
|
||||
transition,
|
||||
repeat,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn is_playing(&self, index: AnimationNodeIndex) -> bool {
|
||||
self.player.is_playing_animation(index)
|
||||
}
|
||||
}
|
||||
|
||||
const DEFAULT_TRANSITION_DURATION: Duration = Duration::from_millis(100);
|
||||
|
||||
fn update_animation(
|
||||
mut animated: Query<(
|
||||
AnimationController,
|
||||
&CharacterAnimations,
|
||||
&mut AnimationFlags,
|
||||
)>,
|
||||
) {
|
||||
for (mut controller, anims, mut flags) in animated.iter_mut() {
|
||||
if flags.shooting && flags.any_direction && anims.run_shoot.is_some() {
|
||||
if !controller.is_playing(anims.run_shoot.unwrap()) {
|
||||
controller.play(
|
||||
anims.run_shoot.unwrap(),
|
||||
DEFAULT_TRANSITION_DURATION,
|
||||
RepeatAnimation::Forever,
|
||||
);
|
||||
}
|
||||
} else if flags.shooting && anims.shoot.is_some() {
|
||||
if !controller.is_playing(anims.shoot.unwrap()) {
|
||||
controller.play(
|
||||
anims.shoot.unwrap(),
|
||||
DEFAULT_TRANSITION_DURATION,
|
||||
RepeatAnimation::Forever,
|
||||
);
|
||||
}
|
||||
} else if flags.hit {
|
||||
if !controller.is_playing(anims.hit) {
|
||||
controller.play(
|
||||
anims.hit,
|
||||
DEFAULT_TRANSITION_DURATION,
|
||||
RepeatAnimation::Never,
|
||||
);
|
||||
}
|
||||
} else if flags.jumping {
|
||||
if !controller.is_playing(anims.jump) || flags.just_jumped {
|
||||
controller.play(
|
||||
anims.jump,
|
||||
DEFAULT_TRANSITION_DURATION,
|
||||
RepeatAnimation::Never,
|
||||
);
|
||||
flags.just_jumped = false;
|
||||
}
|
||||
} else if flags.any_direction {
|
||||
if !controller.player.is_playing_animation(anims.run) {
|
||||
controller.play(
|
||||
anims.run,
|
||||
DEFAULT_TRANSITION_DURATION,
|
||||
RepeatAnimation::Forever,
|
||||
);
|
||||
}
|
||||
} else if !controller.is_playing(anims.idle) {
|
||||
controller.play(
|
||||
anims.idle,
|
||||
DEFAULT_TRANSITION_DURATION,
|
||||
RepeatAnimation::Forever,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user