Using animations for card rotation!

Now to add deal and discard animations...
main
Elijah Voigt 1 year ago
parent d7fc9a12bf
commit 41bbca55cc

@ -1,6 +1,9 @@
use bevy::prelude::*;
use bevy::{
animation::{AnimationTarget, AnimationTargetId},
prelude::*,
};
use crate::{deck::Card, menu::UiMessage, setup::CardAnimations, GameState};
use crate::{deck::Card, menu::UiMessage, setup::AnimationStore, GameState};
pub struct PlayPlugin;
@ -36,21 +39,27 @@ pub(crate) struct SetNumber(pub u8);
pub(crate) fn toggle_selected(
trigger: Trigger<Pointer<Click>>,
mut commands: Commands,
query: Query<&Selected>,
mut players: Query<(&mut AnimationPlayer, &CardAnimations)>,
selections: Query<&Selected>,
mut query: Query<(&Name, &mut AnimationPlayer)>,
store: Res<AnimationStore>,
) {
commands.trigger(UiMessage("".into()));
let e = trigger.entity();
if query.contains(e) {
let (g, ai) = store.store.get("rotate".into()).unwrap();
let (n, mut ap) = query.get_mut(e).unwrap();
ap.stop_all();
if selections.contains(e) {
commands.entity(e).remove::<Selected>();
info!("stopping animation");
let (mut player, anims) = players.get_mut(e).unwrap();
player.stop(anims.rotate);
} else {
commands.entity(e).insert(Selected);
info!("starting animation");
let (mut player, anims) = players.get_mut(e).unwrap();
player.play(anims.rotate);
ap.play(ai.clone()).repeat();
commands.entity(e).insert((
Selected,
g.clone(),
AnimationTarget {
id: AnimationTargetId::from_name(n),
player: e,
},
));
}
}

@ -2,8 +2,9 @@ use std::f32::consts::PI;
use crate::{deck::*, *};
use bevy::{
animation::{animated_field, AnimationTarget, AnimationTargetId},
animation::{animated_field, AnimationTargetId},
prelude::*,
utils::HashMap,
};
use view::ViewState;
@ -13,23 +14,25 @@ impl Plugin for SetupPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
OnEnter(GameState::Setup),
(setup_background, setup_cards, setup_camera, start_play).chain(),
(
setup_background,
setup_cards,
setup_camera,
start_play,
setup_animations,
)
.chain(),
);
}
}
#[derive(Component)]
pub(crate) struct CardAnimations {
pub rotate: AnimationNodeIndex,
#[derive(Resource, Default)]
pub(crate) struct AnimationStore {
pub store: HashMap<String, (AnimationGraphHandle, AnimationNodeIndex)>,
}
/// Setup drawing our cards on the screen
pub(crate) fn setup_cards(
mut commands: Commands,
deck: Res<Deck>,
mut clips: ResMut<Assets<AnimationClip>>,
mut graphs: ResMut<Assets<AnimationGraph>>,
) {
pub(crate) fn setup_cards(mut commands: Commands, deck: Res<Deck>) {
let animation_player = AnimationPlayer::default();
commands
.spawn((
@ -53,40 +56,9 @@ pub(crate) fn setup_cards(
};
let order = play::DeckOrder(i as u8);
let animation_player = AnimationPlayer::default();
let name = Name::new(format!("{}", this_card));
let animation_components = {
let mut animation = AnimationClip::default();
let target = AnimationTargetId::from_name(&name);
let curve = AnimatableCurve::new(
animated_field!(Transform::rotation),
AnimatableKeyframeCurve::new(
[0.0, 1.0, 2.0, 3.0, 4.0].into_iter().zip([
Quat::IDENTITY,
Quat::from_axis_angle(Vec3::Y, PI / 2.),
Quat::from_axis_angle(Vec3::Y, PI / 2. * 2.),
Quat::from_axis_angle(Vec3::Y, PI / 2. * 3.),
Quat::IDENTITY,
]),
)
.expect("Rotation animation"),
);
animation.add_curve_to_target(target, curve);
let animation_handle = clips.add(animation);
let (graph, rotate) = AnimationGraph::from_clip(animation_handle);
let animation_graph_handle = AnimationGraphHandle(graphs.add(graph));
let indexes = CardAnimations { rotate };
let target = AnimationTarget {
id: target,
player: parent.parent_entity(),
};
(animation_graph_handle, indexes, target)
};
// Card Animations:
// active_card_animation = AnimationClip::default() // simple rotation
// for each (X, Y) in board:
// deck_to_X_Y = AnimationClip::default() // Move from deck to X Y position
// X_Y_to_sets = AnimationClip::default() // Move from X Y position to sets pile
// All need AnimationTarget, AnimationGraphHandle, and AnimationPlayer
parent
.spawn((
this_sprite,
@ -94,7 +66,7 @@ pub(crate) fn setup_cards(
order,
Visibility::Hidden,
name,
animation_components,
animation_player,
))
.observe(play::place_card)
.observe(debug::set_debug_card)
@ -105,6 +77,60 @@ pub(crate) fn setup_cards(
});
}
fn setup_animations(
mut clips: ResMut<Assets<AnimationClip>>,
mut graphs: ResMut<Assets<AnimationGraph>>,
mut commands: Commands,
) {
let mut animation_store = AnimationStore::default();
let targets: Vec<AnimationTargetId> = Deck::iter_cards()
.map(|c| Name::new(format!("{}", c)))
.map(|n| AnimationTargetId::from_name(&n))
.collect();
// Rotation Animation
{
let mut animation = AnimationClip::default();
targets.iter().for_each(|target| {
let curve = AnimatableCurve::new(
animated_field!(Transform::rotation),
AnimatableKeyframeCurve::new(
[0.0, 1.0, 2.0, 3.0, 4.0]
.map(|i| i * 5.0) // TODO: Make this tuneable
.into_iter()
.zip([
Quat::IDENTITY,
Quat::from_axis_angle(Vec3::Z, PI / 2.),
Quat::from_axis_angle(Vec3::Z, PI / 2. * 2.),
Quat::from_axis_angle(Vec3::Z, PI / 2. * 3.),
Quat::IDENTITY,
]),
)
.expect("Rotation animation"),
);
animation.add_curve_to_target(*target, curve);
});
let animation_handle = clips.add(animation);
let (graph, animation_index) = AnimationGraph::from_clip(animation_handle);
let graph_handle = AnimationGraphHandle(graphs.add(graph));
animation_store
.store
.insert("rotate".into(), (graph_handle, animation_index));
}
commands.insert_resource(animation_store);
// Card Animations:
// active_card_animation = AnimationClip::default() // simple rotation
// for each (X, Y) in board:
// deck_to_X_Y = AnimationClip::default() // Move from deck to X Y position
// X_Y_to_sets = AnimationClip::default() // Move from X Y position to sets pile
// All need AnimationTarget, AnimationGraphHandle, and AnimationPlayer
// TODO: (example: https://bevyengine.org/examples/animation/animated-transform/)
// Button Animations:
// active_button_animation = AnimationClip::default() // color and size
}
/// Setup our camera to view cardson the screen
pub(crate) fn setup_camera(mut commands: Commands) {
commands.spawn((
@ -140,9 +166,3 @@ pub(crate) fn start_play(
game_state.set(GameState::Main);
view_state.set(ViewState::Menu);
}
fn setup_animations(mut commands: Commands) {
// TODO: (example: https://bevyengine.org/examples/animation/animated-transform/)
// Button Animations:
// active_button_animation = AnimationClip::default() // color and size
}

Loading…
Cancel
Save