diff --git a/examples/the-dungeon-puzzlers-lament/src/game/simulation/animation.rs b/examples/the-dungeon-puzzlers-lament/src/game/simulation/animation.rs index b4a2b4a0..025ea47e 100644 --- a/examples/the-dungeon-puzzlers-lament/src/game/simulation/animation.rs +++ b/examples/the-dungeon-puzzlers-lament/src/game/simulation/animation.rs @@ -6,7 +6,7 @@ use core::ops::{Deref, DerefMut}; use agb::{ display::object::{OamIterator, ObjectUnmanaged, SpriteLoader}, - fixnum::{Num, Vector2D}, + fixnum::{num, Num, Vector2D}, }; use alloc::vec::Vec; use slotmap::SecondaryMap; @@ -52,7 +52,10 @@ impl ToPlay { AnimationInstruction::Move(e, p, s) => { self.moves.push(Move(e, convert_to_real_space(p), s)); } - AnimationInstruction::FakeOutMove(e, d, s) => self.fakeout.push(FakeOutMove(e, d, s)), + AnimationInstruction::FakeOutMove(e, d, p, s) => { + self.fakeout + .push(FakeOutMove(e, d, p.map(|p| convert_to_real_space(p)), s)) + } AnimationInstruction::Detatch(e, nk, s) => self.detatch.push(Detatch(e, nk, s)), AnimationInstruction::Attach(e, o, s) => { if let Some(entity_to_attach) = map.get(o) { @@ -249,8 +252,13 @@ impl Animation { for m in self.to_play.fakeout.drain(0..) { let entity = m.0; + let destination = m.2; - self.map.set_entity_to_start_location(entity); + if let Some(destination) = destination { + self.map.set_entity_start_location(entity, destination); + } else { + self.map.set_entity_to_start_location(entity); + } } for m in self.to_play.attach_progress.drain(0..) { @@ -281,18 +289,33 @@ impl Animation { for m in self.to_play.fakeout.iter_mut() { let entity = m.0; - let direction = m.1; - let direction = convert_to_real_space(direction.into()); - - sfx.play_sound_effect(m.2.take()); - - let go_to = direction / 2; - - let start = (self.ease * 2 - 1).abs(); - let end_multiplier = -start + 1; - if let Some(entity) = self.map.get_mut(entity) { - let location = entity.start_position + go_to * end_multiplier; + let direction = m.1; + let destination = m.2.unwrap_or(entity.start_position); + let direction = convert_to_real_space(direction.into()); + + sfx.play_sound_effect(m.3.take()); + + let go_to = destination + direction / 2; + + let mix = (self.ease * 2 - 1).abs(); + let start_position_mix = if self.ease <= num!(0.5) { + mix + } else { + 0.into() + }; + + let end_position_mix = if self.ease >= num!(0.5) { + mix + } else { + 0.into() + }; + + let intermediate_position_mix = -mix + 1; + + let location = entity.start_position * start_position_mix + + go_to * intermediate_position_mix + + destination * end_position_mix; entity.rendered_position = location; } @@ -386,7 +409,12 @@ impl Animation { } struct Move(EntityKey, Vector2D>, Option); -struct FakeOutMove(EntityKey, Direction, Option); +struct FakeOutMove( + EntityKey, + Direction, + Option>>, + Option, +); struct Detatch(EntityKey, EntityKey, Option); struct Attach(EntityKey, Item, EntityKey, Option); struct AttachProgress(EntityKey, Option); @@ -397,7 +425,12 @@ struct Change(EntityKey, Item, Option); pub enum AnimationInstruction { Add(EntityKey, Item, Vector2D, Option), Move(EntityKey, Vector2D, Option), - FakeOutMove(EntityKey, Direction, Option), + FakeOutMove( + EntityKey, + Direction, + Option>, + Option, + ), Detatch(EntityKey, EntityKey, Option), Attach(EntityKey, EntityKey, Option), Change(EntityKey, Item, Option), diff --git a/examples/the-dungeon-puzzlers-lament/src/game/simulation/entity.rs b/examples/the-dungeon-puzzlers-lament/src/game/simulation/entity.rs index ca5b92b6..09541d5c 100644 --- a/examples/the-dungeon-puzzlers-lament/src/game/simulation/entity.rs +++ b/examples/the-dungeon-puzzlers-lament/src/game/simulation/entity.rs @@ -182,11 +182,7 @@ impl EntityMap { return (can_move, hero_has_died, win_has_triggered); }; - animations.push(AnimationInstruction::Move( - entity_to_update_key, - desired_location, - entity_to_update.move_effect(), - )); + let move_effect = entity_to_update.move_effect(); let overlap_resolutions: Vec<_> = self .whats_at(desired_location) @@ -194,6 +190,17 @@ impl EntityMap { .map(|(key, other_entity)| (key, resolve_overlap(entity_to_update, other_entity))) .collect(); + if !overlap_resolutions + .iter() + .any(|x| matches!(x.1, OverlapResolution::MoveAgain)) + { + animations.push(AnimationInstruction::Move( + entity_to_update_key, + desired_location, + move_effect, + )); + } + for (other_entity_key, move_resolution) in overlap_resolutions { match move_resolution { OverlapResolution::Pickup => { @@ -277,6 +284,7 @@ impl EntityMap { animations.push(AnimationInstruction::FakeOutMove( entity_to_update_key, direction, + self.map.get(entity_to_update_key).map(|e| e.location), if explicit_stay_put { self.map .get(entity_to_update_key)