proof_engine/curves/
curve_anim.rs1use glam::Vec2;
4use super::entity_curves::CurveEntity;
5
6#[derive(Debug, Clone, Copy, PartialEq)]
8pub enum CurveAnimState {
9 Idle,
10 Cast { duration: f32 },
11 Hit { direction: Vec2, magnitude: f32 },
12 Defend,
13 LowHP,
14 Channel { duration: f32 },
15 Dissolving,
16}
17
18#[derive(Debug, Clone)]
20pub struct CurveAnimator {
21 pub current: CurveAnimState,
22 pub previous: CurveAnimState,
23 pub blend: f32,
24 pub blend_speed: f32,
25 pub state_time: f32,
26}
27
28impl CurveAnimator {
29 pub fn new() -> Self {
30 Self { current: CurveAnimState::Idle, previous: CurveAnimState::Idle, blend: 1.0, blend_speed: 5.0, state_time: 0.0 }
31 }
32
33 pub fn transition(&mut self, new_state: CurveAnimState) {
35 if self.current != new_state {
36 self.previous = self.current;
37 self.current = new_state;
38 self.blend = 0.0;
39 self.state_time = 0.0;
40 }
41 }
42
43 pub fn update(&mut self, entity: &mut CurveEntity, dt: f32) {
45 self.state_time += dt;
46 self.blend = (self.blend + self.blend_speed * dt).min(1.0);
47
48 match self.current {
50 CurveAnimState::Cast { duration } => {
51 if self.state_time > duration { self.transition(CurveAnimState::Idle); }
52 }
53 CurveAnimState::Hit { direction, magnitude } => {
54 if self.state_time < dt * 2.0 {
56 entity.apply_hit(direction, magnitude);
57 }
58 if self.state_time > 0.6 { self.transition(CurveAnimState::Idle); }
59 }
60 CurveAnimState::Channel { duration } => {
61 for curve in &mut entity.curves {
63 for (i, vel) in curve.point_velocities.iter_mut().enumerate() {
64 let pt = curve.control_points[i];
65 let tangent = Vec2::new(-pt.y, pt.x).normalize_or_zero();
66 *vel += tangent * 0.5 * dt;
67 }
68 }
69 if self.state_time > duration { self.transition(CurveAnimState::Idle); }
70 }
71 CurveAnimState::Defend => {
72 }
74 CurveAnimState::LowHP => {
75 }
77 CurveAnimState::Dissolving => {
78 }
80 CurveAnimState::Idle => {}
81 }
82
83 entity.breath_amplitude = match self.current {
85 CurveAnimState::Idle => 0.03,
86 CurveAnimState::Cast { .. } => 0.06,
87 CurveAnimState::Hit { .. } => 0.01,
88 CurveAnimState::Defend => 0.01,
89 CurveAnimState::LowHP => 0.05,
90 CurveAnimState::Channel { .. } => 0.04,
91 CurveAnimState::Dissolving => 0.0,
92 };
93 }
94
95 pub fn is_idle(&self) -> bool { self.current == CurveAnimState::Idle }
96 pub fn is_blending(&self) -> bool { self.blend < 1.0 }
97}