diff options
-rw-r--r-- | src/main.cpp | 1 | ||||
-rw-r--r-- | src/sprite.h | 3 | ||||
-rw-r--r-- | src/transform_system.cpp | 79 | ||||
-rw-r--r-- | src/transform_system.h | 31 |
4 files changed, 96 insertions, 18 deletions
diff --git a/src/main.cpp b/src/main.cpp index 4c560c7..4366a4d 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
@@ -27,6 +27,7 @@ void loop(Renderer& renderer) { | |||
27 | 27 | ||
28 | int lucasSprite = game.emplaceSprite(); | 28 | int lucasSprite = game.emplaceSprite(); |
29 | game.getSystem<TransformSystem>().initSprite(lucasSprite, {32, 32}); | 29 | game.getSystem<TransformSystem>().initSprite(lucasSprite, {32, 32}); |
30 | game.getSystem<TransformSystem>().setUpCollision(lucasSprite, {-8, -8}, {12, 8}); | ||
30 | game.getSystem<AnimationSystem>().initSprite(lucasSprite, "../res/sprites/lucas_anim.txt", renderer); | 31 | game.getSystem<AnimationSystem>().initSprite(lucasSprite, "../res/sprites/lucas_anim.txt", renderer); |
31 | game.getSprite(lucasSprite).controllable = true; | 32 | game.getSprite(lucasSprite).controllable = true; |
32 | game.getSystem<CharacterSystem>().initSprite(lucasSprite); | 33 | game.getSystem<CharacterSystem>().initSprite(lucasSprite); |
diff --git a/src/sprite.h b/src/sprite.h index 028008d..e9c6fd0 100644 --- a/src/sprite.h +++ b/src/sprite.h | |||
@@ -33,6 +33,9 @@ public: | |||
33 | 33 | ||
34 | // Transform | 34 | // Transform |
35 | vec2i loc { 0, 0 }; | 35 | vec2i loc { 0, 0 }; |
36 | bool collidable = false; | ||
37 | vec2i collisionOffset; | ||
38 | vec2i collisionSize; | ||
36 | 39 | ||
37 | // Animation | 40 | // Animation |
38 | bool isAnimated = false; | 41 | bool isAnimated = false; |
diff --git a/src/transform_system.cpp b/src/transform_system.cpp index ad7947f..d6df5fa 100644 --- a/src/transform_system.cpp +++ b/src/transform_system.cpp | |||
@@ -8,8 +8,21 @@ void TransformSystem::initSprite(int spriteId, vec2i loc) { | |||
8 | spritesByY_.emplace(loc.y(), spriteId); | 8 | spritesByY_.emplace(loc.y(), spriteId); |
9 | } | 9 | } |
10 | 10 | ||
11 | void TransformSystem::setUpCollision(int spriteId, vec2i offset, vec2i size) { | ||
12 | Sprite& sprite = game_.getSprite(spriteId); | ||
13 | sprite.collidable = true; | ||
14 | sprite.collisionOffset = offset; | ||
15 | sprite.collisionSize = size; | ||
16 | |||
17 | addCollidable(spriteId); | ||
18 | } | ||
19 | |||
11 | void TransformSystem::moveSprite(int spriteId, vec2i newLoc) { | 20 | void TransformSystem::moveSprite(int spriteId, vec2i newLoc) { |
12 | Sprite& sprite = game_.getSprite(spriteId); | 21 | Sprite& sprite = game_.getSprite(spriteId); |
22 | if (sprite.collidable) { | ||
23 | removeCollidable(spriteId); | ||
24 | } | ||
25 | |||
13 | bool changedY = (sprite.loc.y() != newLoc.y()); | 26 | bool changedY = (sprite.loc.y() != newLoc.y()); |
14 | if (changedY) { | 27 | if (changedY) { |
15 | spritesByY_.erase(std::make_tuple(sprite.loc.y(), spriteId)); | 28 | spritesByY_.erase(std::make_tuple(sprite.loc.y(), spriteId)); |
@@ -18,6 +31,9 @@ void TransformSystem::moveSprite(int spriteId, vec2i newLoc) { | |||
18 | if (changedY) { | 31 | if (changedY) { |
19 | spritesByY_.emplace(newLoc.y(), spriteId); | 32 | spritesByY_.emplace(newLoc.y(), spriteId); |
20 | } | 33 | } |
34 | if (sprite.collidable) { | ||
35 | addCollidable(spriteId); | ||
36 | } | ||
21 | } | 37 | } |
22 | 38 | ||
23 | CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Direction dir) { | 39 | CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Direction dir) { |
@@ -28,17 +44,20 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Dire | |||
28 | const Map& map = game_.getMap(); | 44 | const Map& map = game_.getMap(); |
29 | bool blocked = false; | 45 | bool blocked = false; |
30 | 46 | ||
31 | const vec2i UL_COL_BOX = { 8, 8 }; | 47 | vec2i oldColUL = sprite.loc + sprite.collisionOffset; |
32 | const vec2i DR_COL_BOX = { 4, 0 }; | 48 | vec2i oldColDR = oldColUL + sprite.collisionSize; |
33 | vec2i oldColPosUL = (sprite.loc - UL_COL_BOX) / map.getTileSize(); | 49 | vec2i newColUL = newLoc + sprite.collisionOffset; |
34 | vec2i newColPosUL = (newLoc - UL_COL_BOX) / map.getTileSize(); | 50 | vec2i newColDR = newColUL + sprite.collisionSize; |
35 | vec2i oldColPosDR = (sprite.loc + DR_COL_BOX) / map.getTileSize(); | 51 | |
36 | vec2i newColPosDR = (newLoc + DR_COL_BOX) / map.getTileSize(); | 52 | vec2i oldTileUL = oldColUL / map.getTileSize(); |
53 | vec2i newTileUL = newColUL / map.getTileSize(); | ||
54 | vec2i oldTileDR = oldColDR / map.getTileSize(); | ||
55 | vec2i newTileDR = newColDR / map.getTileSize(); | ||
37 | 56 | ||
38 | if (dirHasDir(sprite.dir, Direction::right) && | 57 | if (dirHasDir(sprite.dir, Direction::right) && |
39 | newColPosDR.x() > oldColPosDR.x()) { | 58 | newTileDR.x() > oldTileDR.x()) { |
40 | for (int y = newColPosUL.y(); y <= newColPosDR.y(); y++) { | 59 | for (int y = newTileUL.y(); y <= newTileDR.y(); y++) { |
41 | if (map.isBlocked(newColPosDR.x(), y)) { | 60 | if (map.isBlocked(newTileDR.x(), y)) { |
42 | result.horiz.blocked = true; | 61 | result.horiz.blocked = true; |
43 | result.horiz.dir = Direction::right; | 62 | result.horiz.dir = Direction::right; |
44 | 63 | ||
@@ -48,9 +67,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Dire | |||
48 | } | 67 | } |
49 | 68 | ||
50 | if (dirHasDir(sprite.dir, Direction::left) && | 69 | if (dirHasDir(sprite.dir, Direction::left) && |
51 | newColPosUL.x() < oldColPosUL.x()) { | 70 | newTileUL.x() < oldTileUL.x()) { |
52 | for (int y = newColPosUL.y(); y <= newColPosDR.y(); y++) { | 71 | for (int y = newTileUL.y(); y <= newTileDR.y(); y++) { |
53 | if (map.isBlocked(newColPosUL.x(), y)) { | 72 | if (map.isBlocked(newTileUL.x(), y)) { |
54 | result.horiz.blocked = true; | 73 | result.horiz.blocked = true; |
55 | result.horiz.dir = Direction::left; | 74 | result.horiz.dir = Direction::left; |
56 | 75 | ||
@@ -60,9 +79,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Dire | |||
60 | } | 79 | } |
61 | 80 | ||
62 | if (dirHasDir(sprite.dir, Direction::down) && | 81 | if (dirHasDir(sprite.dir, Direction::down) && |
63 | newColPosDR.y() > oldColPosDR.y()) { | 82 | newTileDR.y() > oldTileDR.y()) { |
64 | for (int x = newColPosUL.x(); x <= newColPosDR.x(); x++) { | 83 | for (int x = newTileUL.x(); x <= newTileDR.x(); x++) { |
65 | if (map.isBlocked(x, newColPosDR.y())) { | 84 | if (map.isBlocked(x, newTileDR.y())) { |
66 | result.vert.blocked = true; | 85 | result.vert.blocked = true; |
67 | result.vert.dir = Direction::down; | 86 | result.vert.dir = Direction::down; |
68 | 87 | ||
@@ -72,9 +91,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Dire | |||
72 | } | 91 | } |
73 | 92 | ||
74 | if (dirHasDir(sprite.dir, Direction::up) && | 93 | if (dirHasDir(sprite.dir, Direction::up) && |
75 | newColPosUL.y() < oldColPosUL.y()) { | 94 | newTileUL.y() < oldTileUL.y()) { |
76 | for (int x = newColPosUL.x(); x <= newColPosDR.x(); x++) { | 95 | for (int x = newTileUL.x(); x <= newTileDR.x(); x++) { |
77 | if (map.isBlocked(x, newColPosUL.y())) { | 96 | if (map.isBlocked(x, newTileUL.y())) { |
78 | result.vert.blocked = true; | 97 | result.vert.blocked = true; |
79 | result.vert.dir = Direction::up; | 98 | result.vert.dir = Direction::up; |
80 | 99 | ||
@@ -85,3 +104,27 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Dire | |||
85 | 104 | ||
86 | return result; | 105 | return result; |
87 | } | 106 | } |
107 | |||
108 | void TransformSystem::addCollidable(int spriteId) { | ||
109 | Sprite& sprite = game_.getSprite(spriteId); | ||
110 | |||
111 | vec2i colUL = sprite.loc + sprite.collisionOffset; | ||
112 | vec2i colDR = colUL + sprite.collisionSize; | ||
113 | |||
114 | leftCollidables_.emplace(std::piecewise_construct, std::tie(colDR.x(), spriteId), std::tie(colUL.y(), colDR.y())); | ||
115 | rightCollidables_.emplace(std::piecewise_construct, std::tie(colUL.x(), spriteId), std::tie(colUL.y(), colDR.y())); | ||
116 | upCollidables_.emplace(std::piecewise_construct, std::tie(colDR.y(), spriteId), std::tie(colUL.x(), colDR.x())); | ||
117 | downCollidables_.emplace(std::piecewise_construct, std::tie(colUL.y(), spriteId), std::tie(colUL.x(), colDR.x())); | ||
118 | } | ||
119 | |||
120 | void TransformSystem::removeCollidable(int spriteId) { | ||
121 | Sprite& sprite = game_.getSprite(spriteId); | ||
122 | |||
123 | vec2i colUL = sprite.loc + sprite.collisionOffset; | ||
124 | vec2i colDR = colUL + sprite.collisionSize; | ||
125 | |||
126 | leftCollidables_.erase({ colDR.x(), spriteId }); | ||
127 | rightCollidables_.erase({ colUL.x(), spriteId }); | ||
128 | upCollidables_.erase({ colDR.y(), spriteId }); | ||
129 | downCollidables_.erase({ colUL.y(), spriteId }); | ||
130 | } | ||
diff --git a/src/transform_system.h b/src/transform_system.h index eb1a95b..1ad661c 100644 --- a/src/transform_system.h +++ b/src/transform_system.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <range/v3/all.hpp> | 4 | #include <range/v3/all.hpp> |
5 | #include <set> | 5 | #include <set> |
6 | #include <map> | ||
6 | #include <tuple> | 7 | #include <tuple> |
7 | #include "direction.h" | 8 | #include "direction.h" |
8 | #include "system.h" | 9 | #include "system.h" |
@@ -29,6 +30,8 @@ public: | |||
29 | 30 | ||
30 | void initSprite(int spriteId, vec2i loc); | 31 | void initSprite(int spriteId, vec2i loc); |
31 | 32 | ||
33 | void setUpCollision(int spriteId, vec2i offset, vec2i size); | ||
34 | |||
32 | void moveSprite(int spriteId, vec2i newLoc); | 35 | void moveSprite(int spriteId, vec2i newLoc); |
33 | 36 | ||
34 | auto getSpritesByY() const { | 37 | auto getSpritesByY() const { |
@@ -43,6 +46,34 @@ private: | |||
43 | 46 | ||
44 | Game& game_; | 47 | Game& game_; |
45 | std::set<std::tuple<int, int>> spritesByY_; | 48 | std::set<std::tuple<int, int>> spritesByY_; |
49 | |||
50 | struct Collidable { | ||
51 | int lower; | ||
52 | int upper; | ||
53 | |||
54 | Collidable(int lower, int upper) : lower(lower), upper(upper) {} | ||
55 | }; | ||
56 | |||
57 | using asc_collidables_type = | ||
58 | std::map< | ||
59 | std::tuple<int, int>, | ||
60 | const Collidable, | ||
61 | std::less<std::tuple<int, int>>>; | ||
62 | |||
63 | using desc_collidables_type = | ||
64 | std::map< | ||
65 | std::tuple<int, int>, | ||
66 | const Collidable, | ||
67 | std::greater<std::tuple<int, int>>>; | ||
68 | |||
69 | desc_collidables_type leftCollidables_; | ||
70 | asc_collidables_type rightCollidables_; | ||
71 | desc_collidables_type upCollidables_; | ||
72 | asc_collidables_type downCollidables_; | ||
73 | |||
74 | void addCollidable(int spriteId); | ||
75 | |||
76 | void removeCollidable(int spriteId); | ||
46 | }; | 77 | }; |
47 | 78 | ||
48 | #endif /* end of include guard: TRANSFORM_SYSTEM_H_BA2633BC */ | 79 | #endif /* end of include guard: TRANSFORM_SYSTEM_H_BA2633BC */ |