skeleton for capture animation flow

main
Elijah C. Voigt 2 years ago
parent a97204c6e4
commit eea2f879d0

4
.gitignore vendored

@ -20,3 +20,7 @@ trace-*.json
*.blend *.blend
*.blend1 *.blend1
# Don't need this
.vscode/

@ -67,7 +67,7 @@ fn fragment(
var n = fbm(pos); var n = fbm(pos);
var cutoff = mat_ext.cutoff; // abs(sin(globals.time)); var cutoff = mat_ext.cutoff;
if n > cutoff { if n > cutoff {
discard; discard;

@ -41,6 +41,7 @@ impl Plugin for Display2dPlugin {
set_sprite.run_if(any_component_changed::<GameSprite>), set_sprite.run_if(any_component_changed::<GameSprite>),
// When tweakfile is updated // When tweakfile is updated
set_sprite.run_if(resource_exists_and_changed::<SpriteSheet>()), set_sprite.run_if(resource_exists_and_changed::<SpriteSheet>()),
capture_piece.run_if(any_component_added::<game::Captured>),
), ),
) )
.add_systems(OnEnter(DisplayState::Display2d), activate::<Display2d>) .add_systems(OnEnter(DisplayState::Display2d), activate::<Display2d>)
@ -389,3 +390,15 @@ fn move_piece(
} }
}) })
} }
/// When a piece is captured, we make it invisible in 2D
fn capture_piece(
mut events: Query<(Entity, &mut Visibility), (With<Display2d>, Added<game::Captured>)>,
mut commands: Commands,
) {
events.iter_mut().for_each(|(entity, mut vis)| {
info!("Hiding captured piece");
*vis = Visibility::Hidden;
commands.entity(entity).remove::<game::Captured>();
});
}

@ -61,8 +61,9 @@ impl Plugin for Display3dPlugin {
any_component_added::<DirectionalLight> any_component_added::<DirectionalLight>
.or_else(any_component_added::<SpotLight>) .or_else(any_component_added::<SpotLight>)
.or_else(any_component_added::<PointLight>) .or_else(any_component_added::<PointLight>)
.or_else(on_event::<AssetEvent<Tweaks>>()) .or_else(on_event::<AssetEvent<Tweaks>>()),
), ),
capture_piece.run_if(any_with_component::<game::Captured>()),
), ),
) )
.add_systems( .add_systems(
@ -473,6 +474,26 @@ fn board_translation(&BoardIndex { x, y }: &BoardIndex) -> Vec3 {
Vec3::new(x, 0.0, y) Vec3::new(x, 0.0, y)
} }
fn capture_translation(side: &Side, num: usize) -> Vec3 {
info!("Side: {:?} Num: {:?}", side, num);
match side {
Side::B => {
let x = -((num % 4) as f32 * 1.3 + 4.0); // mod(num, 4)
let z = (num / 4) as f32 * 1.3 + 4.0; // floor(div(num, 4))
let y = -1.3;
info!("Vec3({}, {}, {})", x, y, z);
Vec3::new(x, y, z)
},
Side::A => {
let x = (num % 4) as f32 * 1.3 + 4.0; // mod(num, 4)
let z = -((num / 4) as f32 * 1.3 + 4.0); // floor(div(num, 4))
let y = -1.3;
info!("Vec3({}, {}, {})", x, y, z);
Vec3::new(x, y, z)
}
}
}
fn gizmo_system(mut gizmos: Gizmos) { fn gizmo_system(mut gizmos: Gizmos) {
for y in 0..4 { for y in 0..4 {
for x in 0..8 { for x in 0..8 {
@ -786,6 +807,7 @@ fn moves_gizmo(
/// Spawn 3d "Valid move" indicators when a piece is selected /// Spawn 3d "Valid move" indicators when a piece is selected
/// Another system registers these new entities and associates the correct models and plays animations. /// Another system registers these new entities and associates the correct models and plays animations.
/// TODO: Do not create/delete entities at runtime
fn create_valid_move_entity( fn create_valid_move_entity(
events: Query<&BoardIndex, (With<game::Piece>, Added<game::Selected>, With<Display3d>)>, events: Query<&BoardIndex, (With<game::Piece>, Added<game::Selected>, With<Display3d>)>,
board: Res<Board>, board: Res<Board>,
@ -841,7 +863,7 @@ fn _play_valid_move_animation(_players: Query<&AnimationPlayer>) {
todo!(); todo!();
} }
// TODO: Move this to game.rs // TODO: Do not create/delete entities at runtime
/// Remove "Valid Move" indicators when a piece is de-selected /// Remove "Valid Move" indicators when a piece is de-selected
fn remove_valid_move_entity( fn remove_valid_move_entity(
mut events: RemovedComponents<game::Selected>, mut events: RemovedComponents<game::Selected>,
@ -1025,7 +1047,7 @@ fn scale_lighting(
let directional_tweak = tweak.get::<f32>("display3d_lights_scaling_directional").expect("Directional lighting scalar"); let directional_tweak = tweak.get::<f32>("display3d_lights_scaling_directional").expect("Directional lighting scalar");
directional.iter_mut().for_each(|(entity, mut val, original)| { directional.iter_mut().for_each(|(entity, mut val, original)| {
info!("Scaling directional light {:?}", entity); debug!("Scaling directional light {:?}", entity);
if let Some(Original(v)) = original { if let Some(Original(v)) = original {
val.illuminance = v.illuminance * directional_tweak; val.illuminance = v.illuminance * directional_tweak;
} else { } else {
@ -1036,7 +1058,7 @@ fn scale_lighting(
let spot_tweak = tweak.get::<f32>("display3d_lights_scaling_spot").expect("Spot lighting scalar"); let spot_tweak = tweak.get::<f32>("display3d_lights_scaling_spot").expect("Spot lighting scalar");
spot.iter_mut().for_each(|(entity, mut val, original)| { spot.iter_mut().for_each(|(entity, mut val, original)| {
info!("Scaling spot light {:?}", entity); debug!("Scaling spot light {:?}", entity);
if let Some(Original(v)) = original { if let Some(Original(v)) = original {
val.intensity = v.intensity * spot_tweak; val.intensity = v.intensity * spot_tweak;
} else { } else {
@ -1047,7 +1069,7 @@ fn scale_lighting(
let point_tweak = tweak.get::<f32>("display3d_lights_scaling_point").expect("Point lighting scalar"); let point_tweak = tweak.get::<f32>("display3d_lights_scaling_point").expect("Point lighting scalar");
point.iter_mut().for_each(|(entity, mut val, original)| { point.iter_mut().for_each(|(entity, mut val, original)| {
info!("Scaling point light {:?}", entity); debug!("Scaling point light {:?}", entity);
if let Some(Original(v)) = original { if let Some(Original(v)) = original {
val.intensity = v.intensity * point_tweak; val.intensity = v.intensity * point_tweak;
} else { } else {
@ -1223,3 +1245,73 @@ pub(super) mod tweaks {
} }
} }
} }
/// When a piece is captured...
/// 1. Play a cool "captured" animation and a neat sound
/// 2. Move the piece to the side of the board
/// 3. Play the same "captured" animation in reverse
/// The animation is like a 'beam me up scotty' sorta thing.
fn capture_piece(
mut events: Query<Entity, (With<Display3d>, Added<game::Captured>)>,
mut query: Query<(&mut Visibility, &mut Transform, &Side), (With<Display3d>, With<game::Captured>)>,
mut state: Local<Option<game::CaptureFlow>>,
mut commands: Commands,
) {
match *state {
Some(s) => {
match s {
game::CaptureFlow::FadeOut(entity) => {
let (mut v, _, _) = query
.get_mut(entity)
.expect("Visibility and Transform of captured piece");
// Play fade-out animation
{
error!("Run fade-out animation");
// Move to next state now that animation is done
*state = s.next();
// Hide piece now that animation is done
*v = Visibility::Hidden;
}
},
game::CaptureFlow::Store(entity) => {
let (_, mut t, side) = query
.get_mut(entity)
.expect("Visibility and Transform of captured piece");
// Move piece to next spot at side of table
error!("Move piece to side of table");
// TODO: Dynamic number based on side's score
t.translation = capture_translation(side, 1);
*state = s.next();
},
game::CaptureFlow::FadeIn(entity) => {
let (mut v, _, _) = query
.get_mut(entity)
.expect("Visibility and Transform of captured piece");
// Show piece now that it is moved
*v = Visibility::Inherited;
// Play fade-in animation
{
error!("Run fade-in animation");
// When animation is done, move to next phase of flow
*state = s.next();
}
// Remove the captured component for bookkeeping
commands.entity(entity).remove::<game::Captured>();
}
}
},
None => {
*state = events.iter().next().map(|entity| {
game::CaptureFlow::FadeOut(entity)
});
}
}
}

@ -23,7 +23,6 @@ impl Plugin for GamePlugin {
buttons.just_pressed(MouseButton::Right) buttons.just_pressed(MouseButton::Right)
}), }),
handle_selection.run_if(on_event::<Selection>()), handle_selection.run_if(on_event::<Selection>()),
capture_piece.run_if(any_component_added::<Captured>),
switch_sides.run_if(|input: Res<Input<KeyCode>>| -> bool { switch_sides.run_if(|input: Res<Input<KeyCode>>| -> bool {
input.just_pressed(KeyCode::N) input.just_pressed(KeyCode::N)
}), }),
@ -130,6 +129,29 @@ pub(crate) struct Move {
pub to: Option<BoardIndex>, pub to: Option<BoardIndex>,
} }
/// Enum for the Capture event flow
#[derive(Debug, Clone, Copy, Resource)]
pub(crate) enum CaptureFlow {
// Run the "fade out" animation
FadeOut(Entity),
// Put the captured piece next to the board
Store(Entity),
// Run the "fade in" animation
FadeIn(Entity),
}
impl CaptureFlow {
/// The capture flow so we can move from one "capture flow state" to the next
/// Fade out, then store, then fade in
pub(crate) fn next(&self) -> Option<Self> {
match self {
Self::FadeOut(e) => Some(Self::Store(e.clone())),
Self::Store(e) => Some(Self::FadeIn(e.clone())),
Self::FadeIn(_) => None,
}
}
}
#[derive(Debug, Component, PartialEq, Clone, Default, Copy, Eq, Hash)] #[derive(Debug, Component, PartialEq, Clone, Default, Copy, Eq, Hash)]
pub(crate) struct BoardIndex { pub(crate) struct BoardIndex {
pub x: usize, pub x: usize,
@ -553,14 +575,6 @@ fn cancel_place(current: Query<&BoardIndex, With<Selected>>, mut events: EventWr
}); });
} }
/// When a piece's _BoardIndex_ is removed, we hide that entity from the viewer
fn capture_piece(mut events: Query<&mut Visibility, Added<Captured>>) {
events.iter_mut().for_each(|mut vis| {
info!("Hiding captured piece");
*vis = Visibility::Hidden
});
}
/// Panics if more than two pieces are selected at a time /// Panics if more than two pieces are selected at a time
fn asserts<T: Component>( fn asserts<T: Component>(
selected_pieces: Query<Entity, (With<Piece>, With<T>, With<Selected>)>, selected_pieces: Query<Entity, (With<Piece>, With<T>, With<Selected>)>,

Loading…
Cancel
Save