-
Notifications
You must be signed in to change notification settings - Fork 34
/
Copy pathinput.rs
117 lines (102 loc) · 3.87 KB
/
input.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use ggez::{input::keyboard::KeyCode, Context};
use hecs::{Entity, World};
use std::collections::HashMap;
use crate::components::*;
use crate::constants::*;
use crate::events::*;
pub fn run_input(world: &World, context: &mut Context) {
let mut to_move: Vec<(Entity, KeyCode)> = Vec::new();
let mut events = Vec::new();
// get all the movables and immovables
let mov: HashMap<(u8, u8), Entity> = world
.query::<(&Position, &Movable)>()
.iter()
.map(|t| ((t.1 .0.x, t.1 .0.y), t.0))
.collect::<HashMap<_, _>>();
let immov: HashMap<(u8, u8), Entity> = world
.query::<(&Position, &Immovable)>()
.iter()
.map(|t| ((t.1 .0.x, t.1 .0.y), t.0))
.collect::<HashMap<_, _>>();
for (_, (position, _player)) in world.query::<(&mut Position, &Player)>().iter() {
if context.keyboard.is_key_repeated() {
continue;
}
// Now iterate through current position to the end of the map
// on the correct axis and check what needs to move.
let key = if context.keyboard.is_key_just_pressed(KeyCode::Up) {
KeyCode::Up
} else if context.keyboard.is_key_just_pressed(KeyCode::Down) {
KeyCode::Down
} else if context.keyboard.is_key_just_pressed(KeyCode::Left) {
KeyCode::Left
} else if context.keyboard.is_key_just_pressed(KeyCode::Right) {
KeyCode::Right
} else {
continue;
};
let (start, end, is_x) = match key {
KeyCode::Up => (position.y, 0, false),
KeyCode::Down => (position.y, MAP_HEIGHT - 1, false),
KeyCode::Left => (position.x, 0, true),
KeyCode::Right => (position.x, MAP_WIDTH - 1, true),
_ => continue,
};
let range = if start < end {
(start..=end).collect::<Vec<_>>()
} else {
(end..=start).rev().collect::<Vec<_>>()
};
for x_or_y in range {
let pos = if is_x {
(x_or_y, position.y)
} else {
(position.x, x_or_y)
};
// find a movable
// if it exists, we try to move it and continue
// if it doesn't exist, we continue and try to find an immovable instead
match mov.get(&pos) {
Some(entity) => to_move.push((*entity, key)),
None => {
// find an immovable
// if it exists, we need to stop and not move anything
// if it doesn't exist, we stop because we found a gap
match immov.get(&pos) {
Some(_id) => {
to_move.clear();
events.push(Event::PlayerHitObstacle {});
break;
}
None => break,
}
}
}
}
}
// Update gameplay moves
if !to_move.is_empty() {
let mut query = world.query::<&mut Gameplay>();
let gameplay = query.iter().next().unwrap().1;
gameplay.moves_count += 1;
}
// Now actually move what needs to be moved
for (entity, key) in to_move {
let mut position = world.get::<&mut Position>(entity).unwrap();
match key {
KeyCode::Up => position.y -= 1,
KeyCode::Down => position.y += 1,
KeyCode::Left => position.x -= 1,
KeyCode::Right => position.x += 1,
_ => (),
}
// Fire an event for the entity that just moved
events.push(Event::EntityMoved(EntityMoved { entity }));
}
// Finally add events back into the world
{
let mut query = world.query::<&mut EventQueue>();
let event_queue = query.iter().next().unwrap().1;
event_queue.events.append(&mut events);
}
}