Browse Source

Implement multiples moves

Bastien Sevajol 3 years ago
parent
commit
480e488e2c
9 changed files with 116 additions and 38 deletions
  1. 30 7
      src/behavior/animate.rs
  2. 3 2
      src/behavior/mod.rs
  3. 2 0
      src/behavior/order.rs
  4. 7 1
      src/config.rs
  5. 1 0
      src/main.rs
  6. 18 14
      src/scene/item.rs
  7. 41 13
      src/scene/main.rs
  8. 3 1
      src/ui/mod.rs
  9. 11 0
      src/util.rs

+ 30 - 7
src/behavior/animate.rs View File

2
 use crate::behavior::ItemBehavior;
2
 use crate::behavior::ItemBehavior;
3
 use crate::config::MOVE_TO_REACHED_WHEN_DISTANCE_INFERIOR_AT;
3
 use crate::config::MOVE_TO_REACHED_WHEN_DISTANCE_INFERIOR_AT;
4
 use crate::scene::item::{ItemState, SceneItem, SceneItemModifier};
4
 use crate::scene::item::{ItemState, SceneItem, SceneItemModifier};
5
+use crate::util::velocity_for_behavior;
5
 use std::f32::consts::FRAC_PI_2;
6
 use std::f32::consts::FRAC_PI_2;
6
 
7
 
7
 pub fn digest_next_order(scene_item: &SceneItem) -> Vec<SceneItemModifier> {
8
 pub fn digest_next_order(scene_item: &SceneItem) -> Vec<SceneItemModifier> {
11
     if let Some(next_order) = &scene_item.next_order {
12
     if let Some(next_order) = &scene_item.next_order {
12
         match next_order {
13
         match next_order {
13
             Order::MoveTo(_) => {
14
             Order::MoveTo(_) => {
14
-                scene_item_modifiers.push(SceneItemModifier::SwitchToCurrentOrder);
15
+                scene_item_modifiers.push(SceneItemModifier::SwitchToNextOrder);
15
             }
16
             }
17
+            Order::MoveFastTo(_) => scene_item_modifiers.push(SceneItemModifier::SwitchToNextOrder),
18
+            Order::HideTo(_) => scene_item_modifiers.push(SceneItemModifier::SwitchToNextOrder),
16
         }
19
         }
17
     }
20
     }
18
 
21
 
26
     if let Some(current_order) = &scene_item.current_order {
29
     if let Some(current_order) = &scene_item.current_order {
27
         match current_order {
30
         match current_order {
28
             Order::MoveTo(move_to_scene_point) => {
31
             Order::MoveTo(move_to_scene_point) => {
32
+                // FIXME BS NOW: Change order only if it is not the current order
29
                 scene_item_modifiers.push(SceneItemModifier::ChangeState(ItemState::new(
33
                 scene_item_modifiers.push(SceneItemModifier::ChangeState(ItemState::new(
30
-                    ItemBehavior::WalkingTo(*move_to_scene_point),
34
+                    ItemBehavior::MoveTo(*move_to_scene_point),
35
+                )))
36
+            }
37
+            Order::MoveFastTo(move_to_scene_point) => {
38
+                // FIXME BS NOW: Change order only if it is not the current order
39
+                scene_item_modifiers.push(SceneItemModifier::ChangeState(ItemState::new(
40
+                    ItemBehavior::MoveFastTo(*move_to_scene_point),
41
+                )))
42
+            }
43
+            Order::HideTo(move_to_scene_point) => {
44
+                // FIXME BS NOW: Change order only if it is not the current order
45
+                scene_item_modifiers.push(SceneItemModifier::ChangeState(ItemState::new(
46
+                    ItemBehavior::HideTo(*move_to_scene_point),
31
                 )))
47
                 )))
32
             }
48
             }
33
         }
49
         }
41
 
57
 
42
     match scene_item.state.current_behavior {
58
     match scene_item.state.current_behavior {
43
         ItemBehavior::Standing => {}
59
         ItemBehavior::Standing => {}
44
-        ItemBehavior::WalkingTo(going_to_scene_point)
45
-        | ItemBehavior::CrawlingTo(going_to_scene_point) => {
60
+        ItemBehavior::MoveTo(going_to_scene_point)
61
+        | ItemBehavior::MoveFastTo(going_to_scene_point)
62
+        | ItemBehavior::HideTo(going_to_scene_point) => {
46
             // Note: angle computed by adding FRAC_PI_2 because sprites are north oriented
63
             // Note: angle computed by adding FRAC_PI_2 because sprites are north oriented
47
             scene_item_modifiers.push(SceneItemModifier::ChangeDisplayAngle(
64
             scene_item_modifiers.push(SceneItemModifier::ChangeDisplayAngle(
48
                 f32::atan2(
65
                 f32::atan2(
53
 
70
 
54
             // Check if scene_point reached
71
             // Check if scene_point reached
55
             let distance = going_to_scene_point.distance(scene_item.position);
72
             let distance = going_to_scene_point.distance(scene_item.position);
56
-            if distance < MOVE_TO_REACHED_WHEN_DISTANCE_INFERIOR_AT {
73
+            let velocity = velocity_for_behavior(&scene_item.state.current_behavior)
74
+                .expect("must have velocity here");
75
+            if distance < MOVE_TO_REACHED_WHEN_DISTANCE_INFERIOR_AT * velocity {
57
                 scene_item_modifiers.push(SceneItemModifier::ChangeState(ItemState::new(
76
                 scene_item_modifiers.push(SceneItemModifier::ChangeState(ItemState::new(
58
                     ItemBehavior::Standing,
77
                     ItemBehavior::Standing,
59
                 )));
78
                 )));
79
+
80
+                // Test if reached destination is from an order. If it is, switch to next order.
60
                 if let Some(current_order) = &scene_item.current_order {
81
                 if let Some(current_order) = &scene_item.current_order {
61
                     match current_order {
82
                     match current_order {
62
-                        Order::MoveTo(move_to_scene_point) => {
83
+                        Order::MoveTo(move_to_scene_point)
84
+                        | Order::MoveFastTo(move_to_scene_point)
85
+                        | Order::HideTo(move_to_scene_point) => {
63
                             if *move_to_scene_point == going_to_scene_point {
86
                             if *move_to_scene_point == going_to_scene_point {
64
-                                scene_item_modifiers.push(SceneItemModifier::SwitchToCurrentOrder);
87
+                                scene_item_modifiers.push(SceneItemModifier::SwitchToNextOrder);
65
                             }
88
                             }
66
                         }
89
                         }
67
                     }
90
                     }

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

5
 
5
 
6
 pub enum ItemBehavior {
6
 pub enum ItemBehavior {
7
     Standing, // since
7
     Standing, // since
8
-    CrawlingTo(ScenePoint),
9
-    WalkingTo(ScenePoint),
8
+    HideTo(ScenePoint),
9
+    MoveTo(ScenePoint),
10
+    MoveFastTo(ScenePoint),
10
 }
11
 }

+ 2 - 0
src/behavior/order.rs View File

3
 #[derive(Clone)]
3
 #[derive(Clone)]
4
 pub enum Order {
4
 pub enum Order {
5
     MoveTo(ScenePoint),
5
     MoveTo(ScenePoint),
6
+    MoveFastTo(ScenePoint),
7
+    HideTo(ScenePoint),
6
 }
8
 }

+ 7 - 1
src/config.rs View File

35
 //
35
 //
36
 pub const DEBUG: bool = true;
36
 pub const DEBUG: bool = true;
37
 // Distance from move target point to consider reached
37
 // Distance from move target point to consider reached
38
-pub const MOVE_TO_REACHED_WHEN_DISTANCE_INFERIOR_AT: f32 = 1.0;
38
+pub const MOVE_TO_REACHED_WHEN_DISTANCE_INFERIOR_AT: f32 = 3.0;
39
+// Velocity of move vector
40
+pub const MOVE_VELOCITY: f32 = 1.0;
41
+// Velocity of move fast vector
42
+pub const MOVE_FAST_VELOCITY: f32 = 2.0;
43
+// Velocity of move hide vector
44
+pub const MOVE_HIDE_VELOCITY: f32 = 0.5;

+ 1 - 0
src/main.rs View File

11
 mod physics;
11
 mod physics;
12
 mod scene;
12
 mod scene;
13
 mod ui;
13
 mod ui;
14
+mod util;
14
 
15
 
15
 type WindowPoint = Vec2;
16
 type WindowPoint = Vec2;
16
 type Offset = Vec2;
17
 type Offset = Vec2;

+ 18 - 14
src/scene/item.rs View File

17
     pub tile_height: f32,
17
     pub tile_height: f32,
18
     pub _half_tile_width: f32,
18
     pub _half_tile_width: f32,
19
     pub _half_tile_height: f32,
19
     pub _half_tile_height: f32,
20
+    pub tick_speed: f32,
20
 }
21
 }
21
 
22
 
22
 impl SceneItemSpriteInfo {
23
 impl SceneItemSpriteInfo {
23
     // TODO: ask on rust community if this is performant, or how to make it static
24
     // TODO: ask on rust community if this is performant, or how to make it static
24
     pub fn from_type(type_: &SpriteType) -> Self {
25
     pub fn from_type(type_: &SpriteType) -> Self {
25
-        let (start_y, tile_width, tile_height, tile_count) = match type_ {
26
-            SpriteType::WalkingSoldier => (12.0, 12.0, 12.0, 8),
27
-            SpriteType::CrawlingSoldier => (26.0, 26.0, 26.0, 8),
28
-            SpriteType::StandingSoldier => (0.0, 12.0, 12.0, 1),
26
+        let (start_y, tile_width, tile_height, tile_count, tick_speed) = match type_ {
27
+            SpriteType::WalkingSoldier => (12.0, 12.0, 12.0, 8, 0.5),
28
+            SpriteType::CrawlingSoldier => (26.0, 26.0, 26.0, 8, 1.0),
29
+            SpriteType::StandingSoldier => (0.0, 12.0, 12.0, 1, 0.0),
29
         };
30
         };
30
 
31
 
31
         Self {
32
         Self {
37
             tile_height,
38
             tile_height,
38
             _half_tile_width: tile_width / 2.0,
39
             _half_tile_width: tile_width / 2.0,
39
             _half_tile_height: tile_height / 2.0,
40
             _half_tile_height: tile_height / 2.0,
41
+            tick_speed,
40
         }
42
         }
41
     }
43
     }
42
 }
44
 }
61
     pub grid_position: GridPosition,
63
     pub grid_position: GridPosition,
62
     pub state: ItemState,
64
     pub state: ItemState,
63
     pub meta_events: Vec<MetaEvent>,
65
     pub meta_events: Vec<MetaEvent>,
64
-    pub current_frame: u16,
66
+    pub current_frame: f32,
65
     pub current_order: Option<Order>,
67
     pub current_order: Option<Order>,
66
     pub next_order: Option<Order>,
68
     pub next_order: Option<Order>,
67
     pub display_angle: f32,
69
     pub display_angle: f32,
75
             grid_position: util::grid_position_from_scene_point(&position.clone()),
77
             grid_position: util::grid_position_from_scene_point(&position.clone()),
76
             state,
78
             state,
77
             meta_events: vec![],
79
             meta_events: vec![],
78
-            current_frame: 0,
80
+            current_frame: 0.0,
79
             current_order: None,
81
             current_order: None,
80
             next_order: None,
82
             next_order: None,
81
             display_angle: 0.0,
83
             display_angle: 0.0,
87
     }
89
     }
88
 
90
 
89
     pub fn tick_sprite(&mut self) {
91
     pub fn tick_sprite(&mut self) {
90
-        self.current_frame += 1;
92
+        let sprite_info =self.sprite_info();
93
+        self.current_frame += sprite_info.tick_speed;
91
         // TODO: good way to have sprite info ? performant ?
94
         // TODO: good way to have sprite info ? performant ?
92
-        if self.current_frame >= self.sprite_info().tile_count {
93
-            self.current_frame = 0;
95
+        if self.current_frame as u16 >= sprite_info.tile_count {
96
+            self.current_frame = 0.0;
94
         }
97
         }
95
     }
98
     }
96
 
99
 
98
         let sprite_info = self.sprite_info();
101
         let sprite_info = self.sprite_info();
99
         graphics::DrawParam::new()
102
         graphics::DrawParam::new()
100
             .src(graphics::Rect::new(
103
             .src(graphics::Rect::new(
101
-                current_frame as f32 * sprite_info.relative_tile_width,
104
+                (current_frame as u16) as f32 * sprite_info.relative_tile_width,
102
                 sprite_info.relative_start_y,
105
                 sprite_info.relative_start_y,
103
                 sprite_info.relative_tile_width,
106
                 sprite_info.relative_tile_width,
104
                 sprite_info.relative_tile_height,
107
                 sprite_info.relative_tile_height,
111
         // Here some logical about state, nature (soldier, tank, ...) and current behavior to
114
         // Here some logical about state, nature (soldier, tank, ...) and current behavior to
112
         // determine sprite type
115
         // determine sprite type
113
         match self.state.current_behavior {
116
         match self.state.current_behavior {
114
-            ItemBehavior::CrawlingTo(_) => SpriteType::CrawlingSoldier,
115
-            ItemBehavior::WalkingTo(_) => SpriteType::WalkingSoldier,
117
+            ItemBehavior::HideTo(_) => SpriteType::CrawlingSoldier,
118
+            ItemBehavior::MoveTo(_) => SpriteType::WalkingSoldier,
119
+            ItemBehavior::MoveFastTo(_) => SpriteType::WalkingSoldier,
116
             ItemBehavior::Standing => SpriteType::StandingSoldier,
120
             ItemBehavior::Standing => SpriteType::StandingSoldier,
117
         }
121
         }
118
     }
122
     }
119
 }
123
 }
120
 
124
 
121
 pub enum SceneItemModifier {
125
 pub enum SceneItemModifier {
122
-    SwitchToCurrentOrder,
126
+    SwitchToNextOrder,
123
     ChangeDisplayAngle(f32),
127
     ChangeDisplayAngle(f32),
124
     ChangeState(ItemState),
128
     ChangeState(ItemState),
125
 }
129
 }
127
 pub fn apply_scene_item_modifier(scene_item: &mut SceneItem, modifiers: Vec<SceneItemModifier>) {
131
 pub fn apply_scene_item_modifier(scene_item: &mut SceneItem, modifiers: Vec<SceneItemModifier>) {
128
     for modifier in modifiers {
132
     for modifier in modifiers {
129
         match modifier {
133
         match modifier {
130
-            SceneItemModifier::SwitchToCurrentOrder => {
134
+            SceneItemModifier::SwitchToNextOrder => {
131
                 let next_order = scene_item.next_order.clone();
135
                 let next_order = scene_item.next_order.clone();
132
                 scene_item.current_order = next_order;
136
                 scene_item.current_order = next_order;
133
                 scene_item.next_order = None;
137
                 scene_item.next_order = None;

+ 41 - 13
src/scene/main.rs View File

13
 use crate::behavior::ItemBehavior;
13
 use crate::behavior::ItemBehavior;
14
 use crate::config::{
14
 use crate::config::{
15
     ANIMATE_EACH, DEBUG, DEFAULT_SELECTED_SQUARE_SIDE, DEFAULT_SELECTED_SQUARE_SIDE_HALF,
15
     ANIMATE_EACH, DEBUG, DEFAULT_SELECTED_SQUARE_SIDE, DEFAULT_SELECTED_SQUARE_SIDE_HALF,
16
-    DISPLAY_OFFSET_BY, DISPLAY_OFFSET_BY_SPEED, MAX_FRAME_I, META_EACH,
17
-    MOVE_TO_REACHED_WHEN_DISTANCE_INFERIOR_AT, PHYSICS_EACH, SCENE_ITEMS_CHANGE_ERR_MSG,
18
-    SPRITE_EACH, TARGET_FPS,
16
+    DISPLAY_OFFSET_BY, DISPLAY_OFFSET_BY_SPEED, MAX_FRAME_I, META_EACH, MOVE_FAST_VELOCITY,
17
+    MOVE_HIDE_VELOCITY, MOVE_TO_REACHED_WHEN_DISTANCE_INFERIOR_AT, MOVE_VELOCITY, PHYSICS_EACH,
18
+    SCENE_ITEMS_CHANGE_ERR_MSG, SPRITE_EACH, TARGET_FPS,
19
 };
19
 };
20
 use crate::physics::util::scene_point_from_window_point;
20
 use crate::physics::util::scene_point_from_window_point;
21
 use crate::physics::util::window_point_from_scene_point;
21
 use crate::physics::util::window_point_from_scene_point;
27
 use crate::ui::vertical_menu::{vertical_menu_sprite_info, VerticalMenuSpriteInfo};
27
 use crate::ui::vertical_menu::{vertical_menu_sprite_info, VerticalMenuSpriteInfo};
28
 use crate::ui::MenuItem;
28
 use crate::ui::MenuItem;
29
 use crate::ui::{SceneItemPrepareOrder, UiComponent, UserEvent};
29
 use crate::ui::{SceneItemPrepareOrder, UiComponent, UserEvent};
30
+use crate::util::velocity_for_behavior;
30
 use crate::{Offset, ScenePoint, WindowPoint};
31
 use crate::{Offset, ScenePoint, WindowPoint};
31
 
32
 
32
 pub struct MainState {
33
 pub struct MainState {
174
         }
175
         }
175
 
176
 
176
         if let Some(scene_item_prepare_order) = &self.scene_item_prepare_order {
177
         if let Some(scene_item_prepare_order) = &self.scene_item_prepare_order {
177
-            // TODO: Add order to scene_item
178
             match scene_item_prepare_order {
178
             match scene_item_prepare_order {
179
                 SceneItemPrepareOrder::Move(scene_item_usize) => {
179
                 SceneItemPrepareOrder::Move(scene_item_usize) => {
180
                     let mut scene_item = self.get_scene_item_mut(*scene_item_usize);
180
                     let mut scene_item = self.get_scene_item_mut(*scene_item_usize);
181
                     scene_item.next_order = Some(Order::MoveTo(scene_click_point));
181
                     scene_item.next_order = Some(Order::MoveTo(scene_click_point));
182
                 }
182
                 }
183
+                SceneItemPrepareOrder::MoveFast(scene_item_usize) => {
184
+                    let mut scene_item = self.get_scene_item_mut(*scene_item_usize);
185
+                    scene_item.next_order = Some(Order::MoveFastTo(scene_click_point));
186
+                }
187
+                SceneItemPrepareOrder::Hide(scene_item_usize) => {
188
+                    let mut scene_item = self.get_scene_item_mut(*scene_item_usize);
189
+                    scene_item.next_order = Some(Order::HideTo(scene_click_point));
190
+                }
183
             }
191
             }
184
 
192
 
185
             self.scene_item_prepare_order = None;
193
             self.scene_item_prepare_order = None;
197
                             Some(SceneItemPrepareOrder::Move(scene_item_usize));
205
                             Some(SceneItemPrepareOrder::Move(scene_item_usize));
198
                         self.scene_item_menu = None;
206
                         self.scene_item_menu = None;
199
                     }
207
                     }
200
-                    MenuItem::MoveFast => {}
201
-                    MenuItem::Hide => {}
208
+                    MenuItem::MoveFast => {
209
+                        self.scene_item_prepare_order =
210
+                            Some(SceneItemPrepareOrder::MoveFast(scene_item_usize));
211
+                        self.scene_item_menu = None;
212
+                    }
213
+                    MenuItem::Hide => {
214
+                        self.scene_item_prepare_order =
215
+                            Some(SceneItemPrepareOrder::Hide(scene_item_usize));
216
+                        self.scene_item_menu = None;
217
+                    }
202
                 }
218
                 }
203
             };
219
             };
204
             self.scene_item_menu = None;
220
             self.scene_item_menu = None;
241
         // Scene items movements
257
         // Scene items movements
242
         for scene_item in self.scene_items.iter_mut() {
258
         for scene_item in self.scene_items.iter_mut() {
243
             match scene_item.state.current_behavior {
259
             match scene_item.state.current_behavior {
244
-                ItemBehavior::WalkingTo(scene_point) => {
245
-                    // FIXME BS NOW: velocity
246
-                    let move_vector = (scene_point - scene_item.position).normalize() * 1.0;
260
+                ItemBehavior::Standing => {}
261
+                ItemBehavior::MoveTo(move_to_scene_point)
262
+                | ItemBehavior::MoveFastTo(move_to_scene_point)
263
+                | ItemBehavior::HideTo(move_to_scene_point) => {
264
+                    let velocity = velocity_for_behavior(&scene_item.state.current_behavior)
265
+                        .expect("must have velocity here");
266
+                    let move_vector =
267
+                        (move_to_scene_point - scene_item.position).normalize() * velocity;
247
                     // TODO ici il faut calculer le déplacement réél (en fonction des ticks, etc ...)
268
                     // TODO ici il faut calculer le déplacement réél (en fonction des ticks, etc ...)
248
                     scene_item.position.x += move_vector.x;
269
                     scene_item.position.x += move_vector.x;
249
                     scene_item.position.y += move_vector.y;
270
                     scene_item.position.y += move_vector.y;
250
                     scene_item.grid_position =
271
                     scene_item.grid_position =
251
                         util::grid_position_from_scene_point(&scene_item.position);
272
                         util::grid_position_from_scene_point(&scene_item.position);
252
                 }
273
                 }
253
-                _ => {}
254
             }
274
             }
255
         }
275
         }
256
 
276
 
322
         for scene_item in self.scene_items.iter() {
342
         for scene_item in self.scene_items.iter() {
323
             self.sprite_sheet_batch.add(
343
             self.sprite_sheet_batch.add(
324
                 scene_item
344
                 scene_item
325
-                    .as_draw_param(scene_item.current_frame as f32)
345
+                    .as_draw_param(scene_item.current_frame)
326
                     .dest(scene_item.position.clone()),
346
                     .dest(scene_item.position.clone()),
327
             );
347
             );
328
         }
348
         }
449
     ) -> GameResult<MeshBuilder> {
469
     ) -> GameResult<MeshBuilder> {
450
         if let Some(scene_item_prepare_order) = &self.scene_item_prepare_order {
470
         if let Some(scene_item_prepare_order) = &self.scene_item_prepare_order {
451
             match scene_item_prepare_order {
471
             match scene_item_prepare_order {
452
-                SceneItemPrepareOrder::Move(scene_item_usize) => {
472
+                SceneItemPrepareOrder::Move(scene_item_usize)
473
+                | SceneItemPrepareOrder::MoveFast(scene_item_usize)
474
+                | SceneItemPrepareOrder::Hide(scene_item_usize) => {
475
+                    let color = match &scene_item_prepare_order {
476
+                        SceneItemPrepareOrder::Move(_) => graphics::BLUE,
477
+                        SceneItemPrepareOrder::MoveFast(_) => graphics::MAGENTA,
478
+                        SceneItemPrepareOrder::Hide(_) => graphics::YELLOW,
479
+                    };
480
+
453
                     let scene_item = self.get_scene_item(*scene_item_usize);
481
                     let scene_item = self.get_scene_item(*scene_item_usize);
454
                     mesh_builder.line(
482
                     mesh_builder.line(
455
                         &vec![
483
                         &vec![
460
                             ),
488
                             ),
461
                         ],
489
                         ],
462
                         2.0,
490
                         2.0,
463
-                        graphics::WHITE,
491
+                        color,
464
                     )?;
492
                     )?;
465
                 }
493
                 }
466
             }
494
             }

+ 3 - 1
src/ui/mod.rs View File

22
 }
22
 }
23
 
23
 
24
 pub enum SceneItemPrepareOrder {
24
 pub enum SceneItemPrepareOrder {
25
-    Move(usize), // scene_item usize
25
+    Move(usize),     // scene_item usize
26
+    MoveFast(usize), // scene_item usize
27
+    Hide(usize),     // scene_item usize
26
 }
28
 }
27
 
29
 
28
 #[derive(Clone)]
30
 #[derive(Clone)]

+ 11 - 0
src/util.rs View File

1
+use crate::behavior::ItemBehavior;
2
+use crate::config::{MOVE_FAST_VELOCITY, MOVE_HIDE_VELOCITY, MOVE_VELOCITY};
3
+
4
+pub fn velocity_for_behavior(behavior: &ItemBehavior) -> Option<f32> {
5
+    match behavior {
6
+        ItemBehavior::MoveTo(_) => Some(MOVE_VELOCITY),
7
+        ItemBehavior::MoveFastTo(_) => Some(MOVE_FAST_VELOCITY),
8
+        ItemBehavior::HideTo(_) => Some(MOVE_HIDE_VELOCITY),
9
+        _ => None,
10
+    }
11
+}