Browse Source

reorganise animate code

Bastien Sevajol 3 years ago
parent
commit
3f5ee23a4b
4 changed files with 110 additions and 81 deletions
  1. 74 0
      src/behavior/animate.rs
  2. 2 1
      src/behavior/mod.rs
  3. 25 1
      src/scene/item.rs
  4. 9 79
      src/scene/main.rs

+ 74 - 0
src/behavior/animate.rs View File

@@ -0,0 +1,74 @@
1
+use crate::behavior::order::Order;
2
+use crate::behavior::ItemBehavior;
3
+use crate::config::MOVE_TO_REACHED_WHEN_DISTANCE_INFERIOR_AT;
4
+use crate::scene::item::{ItemState, SceneItem, SceneItemModifier};
5
+use std::f32::consts::FRAC_PI_2;
6
+
7
+pub fn digest_next_order(scene_item: &SceneItem) -> Vec<SceneItemModifier> {
8
+    let mut scene_item_modifiers: Vec<SceneItemModifier> = vec![];
9
+
10
+    // TODO: Compute here if it possible (fear, compatible with current order, etc)
11
+    if let Some(next_order) = &scene_item.next_order {
12
+        match next_order {
13
+            Order::MoveTo(_) => {
14
+                scene_item_modifiers.push(SceneItemModifier::SwitchToCurrentOrder);
15
+            }
16
+        }
17
+    }
18
+
19
+    scene_item_modifiers
20
+}
21
+
22
+pub fn digest_current_order(scene_item: &SceneItem) -> Vec<SceneItemModifier> {
23
+    let mut scene_item_modifiers: Vec<SceneItemModifier> = vec![];
24
+
25
+    // TODO: here, compute state according to order. Ex: if too much fear, move order do not produce walking state
26
+    if let Some(current_order) = &scene_item.current_order {
27
+        match current_order {
28
+            Order::MoveTo(move_to_scene_point) => {
29
+                scene_item_modifiers.push(SceneItemModifier::ChangeState(ItemState::new(
30
+                    ItemBehavior::WalkingTo(*move_to_scene_point),
31
+                )))
32
+            }
33
+        }
34
+    }
35
+
36
+    scene_item_modifiers
37
+}
38
+
39
+pub fn digest_current_behavior(scene_item: &SceneItem) -> Vec<SceneItemModifier> {
40
+    let mut scene_item_modifiers: Vec<SceneItemModifier> = vec![];
41
+
42
+    match scene_item.state.current_behavior {
43
+        ItemBehavior::Standing => {}
44
+        ItemBehavior::WalkingTo(going_to_scene_point)
45
+        | ItemBehavior::CrawlingTo(going_to_scene_point) => {
46
+            // Note: angle computed by adding FRAC_PI_2 because sprites are north oriented
47
+            scene_item_modifiers.push(SceneItemModifier::ChangeDisplayAngle(
48
+                f32::atan2(
49
+                    going_to_scene_point.y - scene_item.position.y,
50
+                    going_to_scene_point.x - scene_item.position.x,
51
+                ) + FRAC_PI_2,
52
+            ));
53
+
54
+            // Check if scene_point reached
55
+            let distance = going_to_scene_point.distance(scene_item.position);
56
+            if distance < MOVE_TO_REACHED_WHEN_DISTANCE_INFERIOR_AT {
57
+                scene_item_modifiers.push(SceneItemModifier::ChangeState(ItemState::new(
58
+                    ItemBehavior::Standing,
59
+                )));
60
+                if let Some(current_order) = &scene_item.current_order {
61
+                    match current_order {
62
+                        Order::MoveTo(move_to_scene_point) => {
63
+                            if *move_to_scene_point == going_to_scene_point {
64
+                                scene_item_modifiers.push(SceneItemModifier::SwitchToCurrentOrder);
65
+                            }
66
+                        }
67
+                    }
68
+                }
69
+            }
70
+        }
71
+    }
72
+
73
+    scene_item_modifiers
74
+}

+ 2 - 1
src/behavior/mod.rs View File

@@ -1,9 +1,10 @@
1
+pub mod animate;
1 2
 pub mod order;
2 3
 
3 4
 use crate::ScenePoint;
4 5
 
5 6
 pub enum ItemBehavior {
6
-    Standing(u32), // since
7
+    Standing, // since
7 8
     CrawlingTo(ScenePoint),
8 9
     WalkingTo(ScenePoint),
9 10
 }

+ 25 - 1
src/scene/item.rs View File

@@ -113,7 +113,31 @@ impl SceneItem {
113 113
         match self.state.current_behavior {
114 114
             ItemBehavior::CrawlingTo(_) => SpriteType::CrawlingSoldier,
115 115
             ItemBehavior::WalkingTo(_) => SpriteType::WalkingSoldier,
116
-            ItemBehavior::Standing(_) => SpriteType::StandingSoldier,
116
+            ItemBehavior::Standing => SpriteType::StandingSoldier,
117
+        }
118
+    }
119
+}
120
+
121
+pub enum SceneItemModifier {
122
+    SwitchToCurrentOrder,
123
+    ChangeDisplayAngle(f32),
124
+    ChangeState(ItemState),
125
+}
126
+
127
+pub fn apply_scene_item_modifier(scene_item: &mut SceneItem, modifiers: Vec<SceneItemModifier>) {
128
+    for modifier in modifiers {
129
+        match modifier {
130
+            SceneItemModifier::SwitchToCurrentOrder => {
131
+                let next_order = scene_item.next_order.clone();
132
+                scene_item.current_order = next_order;
133
+                scene_item.next_order = None;
134
+            }
135
+            SceneItemModifier::ChangeDisplayAngle(new_angle) => {
136
+                scene_item.display_angle = new_angle;
137
+            }
138
+            SceneItemModifier::ChangeState(new_state) => {
139
+                scene_item.state = new_state;
140
+            }
117 141
         }
118 142
     }
119 143
 }

+ 9 - 79
src/scene/main.rs View File

@@ -7,6 +7,7 @@ use ggez::input::keyboard::KeyCode;
7 7
 use ggez::timer::check_update_time;
8 8
 use ggez::{event, graphics, input, Context, GameResult};
9 9
 
10
+use crate::behavior::animate::{digest_current_behavior, digest_current_order, digest_next_order};
10 11
 use crate::behavior::order::Order;
11 12
 use crate::behavior::ItemBehavior;
12 13
 use crate::config::{
@@ -19,7 +20,9 @@ use crate::physics::util::scene_point_from_window_point;
19 20
 use crate::physics::util::window_point_from_scene_point;
20 21
 use crate::physics::GridPosition;
21 22
 use crate::physics::{util, MetaEvent, PhysicEvent};
22
-use crate::scene::item::{ItemState, SceneItem, SceneItemType};
23
+use crate::scene::item::{
24
+    apply_scene_item_modifier, ItemState, SceneItem, SceneItemModifier, SceneItemType,
25
+};
23 26
 use crate::ui::scene_item_menu::SceneItemMenuItem;
24 27
 use crate::ui::{SceneItemPrepareOrder, UiItem, UiSpriteInfo, UserEvent};
25 28
 use crate::{Offset, ScenePoint, WindowPoint};
@@ -73,7 +76,7 @@ impl MainState {
73 76
                 scene_items.push(SceneItem::new(
74 77
                     SceneItemType::Soldier,
75 78
                     ScenePoint::new((x as f32 * 24.0) + 100.0, (y as f32 * 24.0) + 100.0),
76
-                    ItemState::new(ItemBehavior::Standing(0)),
79
+                    ItemState::new(ItemBehavior::Standing),
77 80
                 ));
78 81
             }
79 82
         }
@@ -267,83 +270,10 @@ impl MainState {
267 270
     }
268 271
 
269 272
     fn animate(&mut self) {
270
-        // TODO: ici il faut reflechir a comment organiser les comportements
271
-
272
-        for scene_item in self.scene_items.iter_mut() {
273
-            // for meta_event in &scene_item.meta_events {
274
-            //     match meta_event {
275
-            //         MetaEvent::FeelExplosion => {
276
-            //             scene_item.state = ItemState::new(ItemBehavior::Standing(self.frame_i));
277
-            //         }
278
-            //     }
279
-            // }
280
-
281
-            // match scene_item.state.current_behavior {
282
-            //     ItemBehavior::Crawling => {
283
-            //         scene_item.state =
284
-            //             ItemState::new(ItemBehavior::Walking(util::vec_from_angle(90.0)));
285
-            //     }
286
-            //     ItemBehavior::Walking(_) => {
287
-            //         scene_item.state = ItemState::new(ItemBehavior::Crawling);
288
-            //     }
289
-            //     ItemBehavior::Standing(since) => {
290
-            //         if self.frame_i - since >= 120 {
291
-            //             scene_item.state =
292
-            //                 ItemState::new(ItemBehavior::Walking(util::vec_from_angle(90.0)));
293
-            //         }
294
-            //     }
295
-            // }
296
-            //
297
-            // scene_item.meta_events.drain(..);
298
-
299
-            if let Some(next_order) = &scene_item.next_order {
300
-                // TODO: Compute here if it possible (fear, compatible with current order, etc)
301
-                match next_order {
302
-                    Order::MoveTo(move_to_scene_point) => {
303
-                        scene_item.current_order = Some(Order::MoveTo(*move_to_scene_point));
304
-                    }
305
-                }
306
-                scene_item.next_order = None;
307
-            }
308
-
309
-            // TODO: here, compute state according to order. Ex: if too much fear, move order do not produce walking state
310
-            if let Some(current_order) = &scene_item.current_order {
311
-                match current_order {
312
-                    Order::MoveTo(move_to_scene_point) => {
313
-                        scene_item.state =
314
-                            ItemState::new(ItemBehavior::WalkingTo(*move_to_scene_point));
315
-                    }
316
-                }
317
-            }
318
-
319
-            match scene_item.state.current_behavior {
320
-                ItemBehavior::Standing(_) => {}
321
-                ItemBehavior::WalkingTo(going_to_scene_point)
322
-                | ItemBehavior::CrawlingTo(going_to_scene_point) => {
323
-                    // Note: angle computed by adding FRAC_PI_2 because sprites are north oriented
324
-                    scene_item.display_angle = f32::atan2(
325
-                        going_to_scene_point.y - scene_item.position.y,
326
-                        going_to_scene_point.x - scene_item.position.x,
327
-                    ) + FRAC_PI_2;
328
-
329
-                    // Check if scene_point reached
330
-                    let distance = going_to_scene_point.distance(scene_item.position);
331
-                    println!("{:?}", distance);
332
-                    if distance < MOVE_TO_REACHED_WHEN_DISTANCE_INFERIOR_AT {
333
-                        scene_item.state = ItemState::new(ItemBehavior::Standing(self.frame_i));
334
-                        if let Some(current_order) = &scene_item.current_order {
335
-                            match current_order {
336
-                                Order::MoveTo(move_to_scene_point) => {
337
-                                    if *move_to_scene_point == going_to_scene_point {
338
-                                        // TODO: If multiple moves, setup next move order
339
-                                        scene_item.current_order = None;
340
-                                    }
341
-                                }
342
-                            }
343
-                        }
344
-                    }
345
-                }
346
-            }
273
+        for (i, scene_item) in self.scene_items.iter_mut().enumerate() {
274
+            apply_scene_item_modifier(scene_item, digest_next_order(&scene_item));
275
+            apply_scene_item_modifier(scene_item, digest_current_order(&scene_item));
276
+            apply_scene_item_modifier(scene_item, digest_current_behavior(&scene_item));
347 277
         }
348 278
     }
349 279