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

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

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

113
         match self.state.current_behavior {
113
         match self.state.current_behavior {
114
             ItemBehavior::CrawlingTo(_) => SpriteType::CrawlingSoldier,
114
             ItemBehavior::CrawlingTo(_) => SpriteType::CrawlingSoldier,
115
             ItemBehavior::WalkingTo(_) => SpriteType::WalkingSoldier,
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
 use ggez::timer::check_update_time;
7
 use ggez::timer::check_update_time;
8
 use ggez::{event, graphics, input, Context, GameResult};
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
 use crate::behavior::order::Order;
11
 use crate::behavior::order::Order;
11
 use crate::behavior::ItemBehavior;
12
 use crate::behavior::ItemBehavior;
12
 use crate::config::{
13
 use crate::config::{
19
 use crate::physics::util::window_point_from_scene_point;
20
 use crate::physics::util::window_point_from_scene_point;
20
 use crate::physics::GridPosition;
21
 use crate::physics::GridPosition;
21
 use crate::physics::{util, MetaEvent, PhysicEvent};
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
 use crate::ui::scene_item_menu::SceneItemMenuItem;
26
 use crate::ui::scene_item_menu::SceneItemMenuItem;
24
 use crate::ui::{SceneItemPrepareOrder, UiItem, UiSpriteInfo, UserEvent};
27
 use crate::ui::{SceneItemPrepareOrder, UiItem, UiSpriteInfo, UserEvent};
25
 use crate::{Offset, ScenePoint, WindowPoint};
28
 use crate::{Offset, ScenePoint, WindowPoint};
73
                 scene_items.push(SceneItem::new(
76
                 scene_items.push(SceneItem::new(
74
                     SceneItemType::Soldier,
77
                     SceneItemType::Soldier,
75
                     ScenePoint::new((x as f32 * 24.0) + 100.0, (y as f32 * 24.0) + 100.0),
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
     }
270
     }
268
 
271
 
269
     fn animate(&mut self) {
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