diff options
| -rw-r--r-- | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/direction.cpp | 25 | ||||
| -rw-r--r-- | src/direction.h | 18 | ||||
| -rw-r--r-- | src/entity.h | 7 | ||||
| -rw-r--r-- | src/enums.h | 9 | ||||
| -rw-r--r-- | src/schedule.h | 22 | ||||
| -rw-r--r-- | src/simulation.cpp | 114 | ||||
| -rw-r--r-- | src/simulation.h | 4 |
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 | ||
| 28 | set_property(TARGET dispatcher PROPERTY CXX_STANDARD 17) | 29 | set_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 | |||
| 3 | vec2s 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 | |||
| 15 | Direction 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 | |||
| 6 | enum class Direction { | ||
| 7 | none, | ||
| 8 | left, | ||
| 9 | right, | ||
| 10 | up, | ||
| 11 | down | ||
| 12 | }; | ||
| 13 | |||
| 14 | vec2s posInDir(vec2s orig, Direction dir); | ||
| 15 | |||
| 16 | Direction 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 | ||
| 8 | class Entity { | 9 | class Entity { |
| 9 | public: | 10 | public: |
| @@ -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 | ||
| 11 | enum class Direction { | 11 | enum 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 { | |||
| 5 | public: | 5 | public: |
| 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 | |||
| 36 | private: | 48 | private: |
| 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 | |||
| 338 | vec2s 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 | |||
| 52 | private: | 50 | private: |
| 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_; |
