summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--src/direction.cpp25
-rw-r--r--src/direction.h18
-rw-r--r--src/entity.h7
-rw-r--r--src/enums.h9
-rw-r--r--src/schedule.h22
-rw-r--r--src/simulation.cpp114
-rw-r--r--src/simulation.h4
8 files changed, 160 insertions, 40 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 8800db7..6fabbf3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -23,6 +23,7 @@ add_executable(dispatcher
23 src/main.cpp 23 src/main.cpp
24 src/renderer.cpp 24 src/renderer.cpp
25 src/simulation.cpp 25 src/simulation.cpp
26 src/direction.cpp
26) 27)
27 28
28set_property(TARGET dispatcher PROPERTY CXX_STANDARD 17) 29set_property(TARGET dispatcher PROPERTY CXX_STANDARD 17)
diff --git a/src/direction.cpp b/src/direction.cpp new file mode 100644 index 0000000..cf6409e --- /dev/null +++ b/src/direction.cpp
@@ -0,0 +1,25 @@
1#include "direction.h"
2
3vec2s posInDir(vec2s orig, Direction dir)
4{
5 switch (dir)
6 {
7 case Direction::left: return orig - vec2s { 1, 0 };
8 case Direction::right: return orig + vec2s { 1, 0 };
9 case Direction::up: return orig - vec2s { 0, 1 };
10 case Direction::down: return orig + vec2s { 0, 1 };
11 case Direction::none: return orig;
12 }
13}
14
15Direction oppositeDir(Direction dir)
16{
17 switch (dir)
18 {
19 case Direction::left: return Direction::right;
20 case Direction::right: return Direction::left;
21 case Direction::up: return Direction::down;
22 case Direction::down: return Direction::up;
23 case Direction::none: return Direction::none;
24 }
25}
diff --git a/src/direction.h b/src/direction.h new file mode 100644 index 0000000..8108505 --- /dev/null +++ b/src/direction.h
@@ -0,0 +1,18 @@
1#ifndef DIRECTION_H_2B40D968
2#define DIRECTION_H_2B40D968
3
4#include "vector.h"
5
6enum class Direction {
7 none,
8 left,
9 right,
10 up,
11 down
12};
13
14vec2s posInDir(vec2s orig, Direction dir);
15
16Direction oppositeDir(Direction dir);
17
18#endif /* end of include guard: DIRECTION_H_2B40D968 */
diff --git a/src/entity.h b/src/entity.h index a69c612..c47f1e7 100644 --- a/src/entity.h +++ b/src/entity.h
@@ -4,6 +4,7 @@
4#include <set> 4#include <set>
5#include "vector.h" 5#include "vector.h"
6#include "enums.h" 6#include "enums.h"
7#include "direction.h"
7 8
8class Entity { 9class Entity {
9public: 10public:
@@ -14,6 +15,7 @@ public:
14 15
15 // Grid placement 16 // Grid placement
16 vec2s gridPos; 17 vec2s gridPos;
18 Layer layer = Layer::object;
17 19
18 // Movement 20 // Movement
19 Direction shouldMoveTo = Direction::none; 21 Direction shouldMoveTo = Direction::none;
@@ -35,6 +37,11 @@ public:
35 37
36 bool scheduled = false; 38 bool scheduled = false;
37 39
40 // Track
41 bool isTrack = false;
42 Direction trackDir1 = Direction::none;
43 Direction trackDir2 = Direction::none;
44
38}; 45};
39 46
40#endif /* end of include guard: ENTITY_H_0D6CB29A */ 47#endif /* end of include guard: ENTITY_H_0D6CB29A */
diff --git a/src/enums.h b/src/enums.h index 9821da1..e2056f5 100644 --- a/src/enums.h +++ b/src/enums.h
@@ -8,12 +8,9 @@ enum class ColliderType {
8 other 8 other
9}; 9};
10 10
11enum class Direction { 11enum class Layer {
12 none, 12 track,
13 left, 13 object
14 right,
15 up,
16 down
17}; 14};
18 15
19#endif /* end of include guard: ENUMS_H_CD0A75E4 */ 16#endif /* end of include guard: ENUMS_H_CD0A75E4 */
diff --git a/src/schedule.h b/src/schedule.h index 5d77761..f7c5543 100644 --- a/src/schedule.h +++ b/src/schedule.h
@@ -5,17 +5,23 @@ class Schedule {
5public: 5public:
6 6
7 explicit Schedule( 7 explicit Schedule(
8 size_t bpm) : 8 double bpm) :
9 bpm_(bpm), 9 bpm_(bpm),
10 tick_(60.0 / static_cast<double>(bpm_)) 10 bps_(bpm_ / 60.0),
11 tick_(1.0 / bps_)
11 { 12 {
12 } 13 }
13 14
14 size_t getBPM() const 15 double getBPM() const
15 { 16 {
16 return bpm_; 17 return bpm_;
17 } 18 }
18 19
20 double getBPS() const
21 {
22 return bps_;
23 }
24
19 void accumulate(double dt) 25 void accumulate(double dt)
20 { 26 {
21 accum_ += dt; 27 accum_ += dt;
@@ -26,6 +32,7 @@ public:
26 if (accum_ > tick_) 32 if (accum_ > tick_)
27 { 33 {
28 accum_ -= tick_; 34 accum_ -= tick_;
35 beats_++;
29 36
30 return true; 37 return true;
31 } else { 38 } else {
@@ -33,11 +40,18 @@ public:
33 } 40 }
34 } 41 }
35 42
43 size_t getBeat() const
44 {
45 return beats_;
46 }
47
36private: 48private:
37 49
38 size_t bpm_; 50 double bpm_;
51 double bps_;
39 double tick_; 52 double tick_;
40 double accum_ = 0.0; 53 double accum_ = 0.0;
54 size_t beats_ = 0;
41 55
42}; 56};
43 57
diff --git a/src/simulation.cpp b/src/simulation.cpp index 1379c34..77a9a3e 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp
@@ -1,5 +1,6 @@
1#include "simulation.h" 1#include "simulation.h"
2 2
3#include <range/v3/all.hpp>
3#include "consts.h" 4#include "consts.h"
4#include "level.h" 5#include "level.h"
5 6
@@ -7,6 +8,59 @@ Simulation::Simulation(
7 const Level& level) : 8 const Level& level) :
8 level_(level) 9 level_(level)
9{ 10{
11
12
13 id_type trackId = emplaceEntity();
14 Entity& track = getEntity(trackId);
15 track.size = TILE_SIZE;
16 track.layer = Layer::track;
17 track.isTrack = true;
18 track.trackDir1 = Direction::right;
19 track.trackDir2 = Direction::down;
20 track.colorVal = 130;
21 track.gridPos = vec2s { 6, 1 };
22
23 id_type trackId2 = emplaceEntity();
24 Entity& track2 = getEntity(trackId2);
25 track2.size = TILE_SIZE;
26 track2.layer = Layer::track;
27 track2.isTrack = true;
28 track2.trackDir1 = Direction::right;
29 track2.trackDir2 = Direction::up;
30 track2.colorVal = 130;
31 track2.gridPos = vec2s { 6, 2 };
32
33 id_type trackId3 = emplaceEntity();
34 Entity& track3 = getEntity(trackId3);
35 track3.size = TILE_SIZE;
36 track3.layer = Layer::track;
37 track3.isTrack = true;
38 track3.trackDir1 = Direction::up;
39 track3.trackDir2 = Direction::left;
40 track3.colorVal = 130;
41 track3.gridPos = vec2s { 7, 2 };
42
43 id_type trackId4 = emplaceEntity();
44 Entity& track4 = getEntity(trackId4);
45 track4.size = TILE_SIZE;
46 track4.layer = Layer::track;
47 track4.isTrack = true;
48 track4.trackDir1 = Direction::left;
49 track4.trackDir2 = Direction::down;
50 track4.colorVal = 130;
51 track4.gridPos = vec2s { 7, 1 };
52
53
54 id_type trainId = emplaceEntity();
55 Entity& train = getEntity(trainId);
56 train.size = TILE_SIZE;
57 train.speed = schedule_.getBPS() * 2.0;
58 train.colliderType = ColliderType::train;
59 train.scheduled = true;
60 train.colorVal = 90;
61 train.gridPos = vec2s { 6, 1 };
62 train.moveDir = Direction::left;
63
10 id_type player = emplaceEntity(); 64 id_type player = emplaceEntity();
11 Entity& entity = getEntity(player); 65 Entity& entity = getEntity(player);
12 entity.size = TILE_SIZE; 66 entity.size = TILE_SIZE;
@@ -19,7 +73,7 @@ Simulation::Simulation(
19 id_type crateId = emplaceEntity(); 73 id_type crateId = emplaceEntity();
20 Entity& crate = getEntity(crateId); 74 Entity& crate = getEntity(crateId);
21 crate.size = TILE_SIZE; 75 crate.size = TILE_SIZE;
22 crate.speed = static_cast<double>(schedule_.getBPM()) / 30.0; 76 crate.speed = schedule_.getBPS() * 2.0;
23 crate.colliderType = ColliderType::crate; 77 crate.colliderType = ColliderType::crate;
24 crate.canBePushedBy.insert(ColliderType::player); 78 crate.canBePushedBy.insert(ColliderType::player);
25 crate.canBePushedBy.insert(ColliderType::crate); 79 crate.canBePushedBy.insert(ColliderType::crate);
@@ -29,24 +83,13 @@ Simulation::Simulation(
29 id_type crateId2 = emplaceEntity(); 83 id_type crateId2 = emplaceEntity();
30 Entity& crate2 = getEntity(crateId2); 84 Entity& crate2 = getEntity(crateId2);
31 crate2.size = TILE_SIZE; 85 crate2.size = TILE_SIZE;
32 crate2.speed = static_cast<double>(schedule_.getBPM()) / 30.0; 86 crate2.speed = schedule_.getBPS() * 2.0;
33 crate2.colliderType = ColliderType::crate; 87 crate2.colliderType = ColliderType::crate;
34 crate2.canBePushedBy.insert(ColliderType::player); 88 crate2.canBePushedBy.insert(ColliderType::player);
35 crate2.canBePushedBy.insert(ColliderType::crate); 89 crate2.canBePushedBy.insert(ColliderType::crate);
36 crate2.canBePushedBy.insert(ColliderType::train); 90 crate2.canBePushedBy.insert(ColliderType::train);
37 crate2.gridPos = vec2s { 6, 7 }; 91 crate2.gridPos = vec2s { 6, 7 };
38 92
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 93
51 for (id_type id : active_) 94 for (id_type id : active_)
52 { 95 {
@@ -145,7 +188,28 @@ void Simulation::tick(
145 188
146 if (entity.scheduled && !entity.moving) 189 if (entity.scheduled && !entity.moving)
147 { 190 {
148 moveEntityOnGrid(id, Direction::down); 191 auto tracks =
192 posCache_.at(entity.gridPos) |
193 ranges::view::transform([&] (id_type id) -> Entity& { return entities_.at(id); }) |
194 ranges::view::filter([&] (Entity& other) { return other.isTrack; });
195
196 if (!ranges::empty(tracks))
197 {
198 Entity& track = ranges::front(tracks);
199
200 Direction dir = Direction::none;
201 Direction from = oppositeDir(entity.moveDir);
202
203 if (from == track.trackDir1)
204 {
205 dir = track.trackDir2;
206 } else if (from == track.trackDir2)
207 {
208 dir = track.trackDir1;
209 }
210
211 moveEntityOnGrid(id, dir);
212 }
149 } 213 }
150 } 214 }
151 } 215 }
@@ -282,7 +346,10 @@ bool Simulation::moveEntityOnGrid(
282 } 346 }
283 347
284 // Can't move into a space that something else is already moving into. 348 // Can't move into a space that something else is already moving into.
285 if (!moveToCache_.at(shouldMoveTo).empty()) 349 if (!ranges::empty(
350 moveToCache_.at(shouldMoveTo) |
351 ranges::view::transform([&] (id_type id) -> Entity& { return entities_.at(id); }) |
352 ranges::view::filter([&] (Entity& other) { return other.layer == entity.layer; })))
286 { 353 {
287 return false; 354 return false;
288 } 355 }
@@ -291,6 +358,11 @@ bool Simulation::moveEntityOnGrid(
291 { 358 {
292 Entity& block = entities_.at(blockId); 359 Entity& block = entities_.at(blockId);
293 360
361 if (block.layer != entity.layer)
362 {
363 continue;
364 }
365
294 if (!block.moving) 366 if (!block.moving)
295 { 367 {
296 if (!block.canBePushedBy.count(entity.colliderType)) 368 if (!block.canBePushedBy.count(entity.colliderType))
@@ -334,15 +406,3 @@ bool Simulation::moveEntityOnGrid(
334 406
335 return true; 407 return true;
336} 408}
337
338vec2s Simulation::posInDir(vec2s orig, Direction dir)
339{
340 switch (dir)
341 {
342 case Direction::left: return orig - vec2s { 1, 0 };
343 case Direction::right: return orig + vec2s { 1, 0 };
344 case Direction::up: return orig - vec2s { 0, 1 };
345 case Direction::down: return orig + vec2s { 0, 1 };
346 case Direction::none: return orig;
347 }
348}
diff --git a/src/simulation.h b/src/simulation.h index f86d513..fbe0a43 100644 --- a/src/simulation.h +++ b/src/simulation.h
@@ -47,8 +47,6 @@ public:
47 return level_; 47 return level_;
48 } 48 }
49 49
50 static vec2s posInDir(vec2s orig, Direction dir);
51
52private: 50private:
53 51
54 52
@@ -60,7 +58,7 @@ private:
60 bool validate = false); 58 bool validate = false);
61 59
62 const Level& level_; 60 const Level& level_;
63 Schedule schedule_ { 120 }; 61 Schedule schedule_ { 90 };
64 62
65 std::vector<Entity> entities_; 63 std::vector<Entity> entities_;
66 std::deque<id_type> available_; 64 std::deque<id_type> available_;