diff options
Diffstat (limited to 'src/simulation.cpp')
-rw-r--r-- | src/simulation.cpp | 128 |
1 files changed, 99 insertions, 29 deletions
diff --git a/src/simulation.cpp b/src/simulation.cpp index 912f7f0..1379c34 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp | |||
@@ -3,15 +3,68 @@ | |||
3 | #include "consts.h" | 3 | #include "consts.h" |
4 | #include "level.h" | 4 | #include "level.h" |
5 | 5 | ||
6 | Simulation::Simulation( | ||
7 | const Level& level) : | ||
8 | level_(level) | ||
9 | { | ||
10 | id_type player = emplaceEntity(); | ||
11 | Entity& entity = getEntity(player); | ||
12 | entity.size = TILE_SIZE; | ||
13 | entity.speed = 3.0; | ||
14 | entity.controllable = true; | ||
15 | entity.colliderType = ColliderType::player; | ||
16 | entity.colorVal = 180; | ||
17 | entity.gridPos = vec2s { 1, 5 }; | ||
18 | |||
19 | id_type crateId = emplaceEntity(); | ||
20 | Entity& crate = getEntity(crateId); | ||
21 | crate.size = TILE_SIZE; | ||
22 | crate.speed = static_cast<double>(schedule_.getBPM()) / 30.0; | ||
23 | crate.colliderType = ColliderType::crate; | ||
24 | crate.canBePushedBy.insert(ColliderType::player); | ||
25 | crate.canBePushedBy.insert(ColliderType::crate); | ||
26 | crate.canBePushedBy.insert(ColliderType::train); | ||
27 | crate.gridPos = vec2s { 4, 5 }; | ||
28 | |||
29 | id_type crateId2 = emplaceEntity(); | ||
30 | Entity& crate2 = getEntity(crateId2); | ||
31 | crate2.size = TILE_SIZE; | ||
32 | crate2.speed = static_cast<double>(schedule_.getBPM()) / 30.0; | ||
33 | crate2.colliderType = ColliderType::crate; | ||
34 | crate2.canBePushedBy.insert(ColliderType::player); | ||
35 | crate2.canBePushedBy.insert(ColliderType::crate); | ||
36 | crate2.canBePushedBy.insert(ColliderType::train); | ||
37 | crate2.gridPos = vec2s { 6, 7 }; | ||
38 | |||
39 | id_type trainId = emplaceEntity(); | ||
40 | Entity& train = getEntity(trainId); | ||
41 | train.size = TILE_SIZE; | ||
42 | train.speed = static_cast<double>(schedule_.getBPM()) / 30.0; | ||
43 | train.colliderType = ColliderType::train; | ||
44 | train.scheduled = true; | ||
45 | train.colorVal = 90; | ||
46 | train.gridPos = vec2s { 6, 1 }; | ||
47 | |||
48 | |||
49 | |||
50 | |||
51 | for (id_type id : active_) | ||
52 | { | ||
53 | Entity& entity = entities_.at(id); | ||
54 | |||
55 | posCache_.set(id, entity.gridPos); | ||
56 | } | ||
57 | } | ||
58 | |||
6 | void Simulation::tick( | 59 | void Simulation::tick( |
7 | double dt, | 60 | double dt, |
8 | const Uint8* keystate) | 61 | const Uint8* keystate) |
9 | { | 62 | { |
63 | // Control | ||
10 | for (id_type id : active_) | 64 | for (id_type id : active_) |
11 | { | 65 | { |
12 | Entity& entity = entities_.at(id); | 66 | Entity& entity = entities_.at(id); |
13 | 67 | ||
14 | // Control | ||
15 | if (entity.controllable && | 68 | if (entity.controllable && |
16 | !entity.moving) | 69 | !entity.moving) |
17 | { | 70 | { |
@@ -38,7 +91,7 @@ void Simulation::tick( | |||
38 | 91 | ||
39 | vec2s lookPos = posInDir(entity.gridPos, lookDir); | 92 | vec2s lookPos = posInDir(entity.gridPos, lookDir); |
40 | 93 | ||
41 | for (id_type blockId : getGridEntities(lookPos)) | 94 | for (id_type blockId : posCache_.at(lookPos)) |
42 | { | 95 | { |
43 | Entity& block = entities_.at(blockId); | 96 | Entity& block = entities_.at(blockId); |
44 | 97 | ||
@@ -79,16 +132,40 @@ void Simulation::tick( | |||
79 | } | 132 | } |
80 | } | 133 | } |
81 | } | 134 | } |
135 | } | ||
136 | |||
137 | // Schedule | ||
138 | schedule_.accumulate(dt); | ||
139 | |||
140 | if (schedule_.step()) | ||
141 | { | ||
142 | for (id_type id : active_) | ||
143 | { | ||
144 | Entity& entity = entities_.at(id); | ||
145 | |||
146 | if (entity.scheduled && !entity.moving) | ||
147 | { | ||
148 | moveEntityOnGrid(id, Direction::down); | ||
149 | } | ||
150 | } | ||
151 | } | ||
152 | |||
82 | 153 | ||
83 | 154 | ||
84 | 155 | ||
85 | 156 | ||
86 | // Collision | ||
87 | 157 | ||
88 | 158 | ||
159 | // Collision | ||
89 | 160 | ||
90 | 161 | ||
91 | // Movement | 162 | |
163 | |||
164 | // Movement | ||
165 | for (id_type id : active_) | ||
166 | { | ||
167 | Entity& entity = entities_.at(id); | ||
168 | |||
92 | if (entity.moving) | 169 | if (entity.moving) |
93 | { | 170 | { |
94 | entity.movementTween += entity.speed * dt; | 171 | entity.movementTween += entity.speed * dt; |
@@ -96,7 +173,9 @@ void Simulation::tick( | |||
96 | if (entity.movementTween >= 1.0) | 173 | if (entity.movementTween >= 1.0) |
97 | { | 174 | { |
98 | entity.moving = false; | 175 | entity.moving = false; |
99 | setGridPos(id, entity.destPos); | 176 | entity.gridPos = entity.destPos; |
177 | posCache_.set(id, entity.gridPos); | ||
178 | moveToCache_.remove(id); | ||
100 | } | 179 | } |
101 | } | 180 | } |
102 | 181 | ||
@@ -141,29 +220,6 @@ void Simulation::deleteEntity(id_type id) | |||
141 | active_.erase(id); | 220 | active_.erase(id); |
142 | } | 221 | } |
143 | 222 | ||
144 | void Simulation::setGridPos(id_type id, vec2s pos) | ||
145 | { | ||
146 | Entity& entity = entities_.at(id); | ||
147 | |||
148 | size_t oldPosIndex = | ||
149 | entity.gridPos.x() + entity.gridPos.y() * level_.getSize().w(); | ||
150 | gridCache_[oldPosIndex].erase(id); | ||
151 | |||
152 | entity.gridPos = pos; | ||
153 | |||
154 | size_t newPosIndex = | ||
155 | entity.gridPos.x() + entity.gridPos.y() * level_.getSize().w(); | ||
156 | gridCache_[newPosIndex].insert(id); | ||
157 | } | ||
158 | |||
159 | const std::unordered_set<Simulation::id_type>& | ||
160 | Simulation::getGridEntities(vec2s pos) const | ||
161 | { | ||
162 | size_t posIndex = pos.x() + pos.y() * level_.getSize().w(); | ||
163 | |||
164 | return gridCache_[posIndex]; | ||
165 | } | ||
166 | |||
167 | bool Simulation::moveEntityOnGrid( | 223 | bool Simulation::moveEntityOnGrid( |
168 | id_type id, | 224 | id_type id, |
169 | Direction moveDir, | 225 | Direction moveDir, |
@@ -225,7 +281,13 @@ bool Simulation::moveEntityOnGrid( | |||
225 | return false; | 281 | return false; |
226 | } | 282 | } |
227 | 283 | ||
228 | for (id_type blockId : getGridEntities(shouldMoveTo)) | 284 | // Can't move into a space that something else is already moving into. |
285 | if (!moveToCache_.at(shouldMoveTo).empty()) | ||
286 | { | ||
287 | return false; | ||
288 | } | ||
289 | |||
290 | for (id_type blockId : posCache_.at(shouldMoveTo)) | ||
229 | { | 291 | { |
230 | Entity& block = entities_.at(blockId); | 292 | Entity& block = entities_.at(blockId); |
231 | 293 | ||
@@ -240,6 +302,11 @@ bool Simulation::moveEntityOnGrid( | |||
240 | { | 302 | { |
241 | return false; | 303 | return false; |
242 | } | 304 | } |
305 | } else if (block.moveDir != moveDir) | ||
306 | { | ||
307 | // Can't move perpendicularly into a space that something else is moving | ||
308 | // out of. | ||
309 | return false; | ||
243 | } | 310 | } |
244 | 311 | ||
245 | double entityTimeLeft = 1.0 / entity.speed; | 312 | double entityTimeLeft = 1.0 / entity.speed; |
@@ -260,6 +327,9 @@ bool Simulation::moveEntityOnGrid( | |||
260 | entity.moving = true; | 327 | entity.moving = true; |
261 | entity.destPos = shouldMoveTo; | 328 | entity.destPos = shouldMoveTo; |
262 | entity.movementTween = 0.0; | 329 | entity.movementTween = 0.0; |
330 | entity.moveDir = moveDir; | ||
331 | |||
332 | moveToCache_.set(id, entity.destPos); | ||
263 | } | 333 | } |
264 | 334 | ||
265 | return true; | 335 | return true; |