summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/main.cpp1
-rw-r--r--src/sprite.h3
-rw-r--r--src/transform_system.cpp79
-rw-r--r--src/transform_system.h31
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
11void 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
11void TransformSystem::moveSprite(int spriteId, vec2i newLoc) { 20void 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
23CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Direction dir) { 39CollisionResult 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
108void 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
120void 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 */