summary refs log tree commit diff stats
path: root/src/transform_system.cpp
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2021-03-11 16:06:19 -0500
committerStar Rauchenberger <fefferburbia@gmail.com>2021-03-11 17:33:15 -0500
commiteb9fa5020317a44f17cc4906c4c1c6fe55700d3e (patch)
treee4cb67d97818e06d974d0fca987dd76f25affdf9 /src/transform_system.cpp
parent4c29543e44deb7a327b21b0af6a85a92e83ff103 (diff)
downloadtanetane-eb9fa5020317a44f17cc4906c4c1c6fe55700d3e.tar.gz
tanetane-eb9fa5020317a44f17cc4906c4c1c6fe55700d3e.tar.bz2
tanetane-eb9fa5020317a44f17cc4906c4c1c6fe55700d3e.zip
Simplified collision detection output
It is no longer split into horizontal and vertical results. Also, the collision detection routine now does the work of calculating an adjusted position, instead of the caller (CharacterSystem) having to do it. This will be useful for #3.
Diffstat (limited to 'src/transform_system.cpp')
-rw-r--r--src/transform_system.cpp84
1 files changed, 47 insertions, 37 deletions
diff --git a/src/transform_system.cpp b/src/transform_system.cpp index 4ed47c0..a643255 100644 --- a/src/transform_system.cpp +++ b/src/transform_system.cpp
@@ -59,6 +59,7 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
59 59
60 // First check horizontal movement only. 60 // First check horizontal movement only.
61 vec2i horizMovement = { newLoc.x(), curLoc.y() }; 61 vec2i horizMovement = { newLoc.x(), curLoc.y() };
62 bool horizBlocked = false;
62 63
63 vec2i oldColUL = curLoc + sprite.collisionOffset; 64 vec2i oldColUL = curLoc + sprite.collisionOffset;
64 vec2i oldColDR = oldColUL + sprite.collisionSize - vec2i{1,1}; 65 vec2i oldColDR = oldColUL + sprite.collisionSize - vec2i{1,1};
@@ -80,23 +81,23 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
80 newColDR.x() < mapBounds.w()) { 81 newColDR.x() < mapBounds.w()) {
81 for (int y = newTileUL.y(); y <= newTileDR.y(); y++) { 82 for (int y = newTileUL.y(); y <= newTileDR.y(); y++) {
82 if (map.isBlocked(newTileDR.x(), y)) { 83 if (map.isBlocked(newTileDR.x(), y)) {
83 result.horiz.blocked = true; 84 horizBlocked = true;
84 result.horiz.dir = Direction::right; 85 result.dir = Direction::right;
85 86
86 break; 87 break;
87 } 88 }
88 } 89 }
89 } 90 }
90 91
91 if (!result.horiz.blocked && enclosureZone) { 92 if (!horizBlocked && enclosureZone) {
92 if (oldColDR.x() <= enclosureZone->dr.x()-1 && 93 if (oldColDR.x() <= enclosureZone->dr.x()-1 &&
93 newColDR.x() > enclosureZone->dr.x()-1) { 94 newColDR.x() > enclosureZone->dr.x()-1) {
94 result.horiz.blocked = true; 95 horizBlocked = true;
95 result.horiz.dir = Direction::right; 96 result.dir = Direction::right;
96 } 97 }
97 } 98 }
98 99
99 if (!result.horiz.blocked) { 100 if (!horizBlocked) {
100 auto it = rightCollidables_.lower_bound({oldColDR.x()+1, 0}); 101 auto it = rightCollidables_.lower_bound({oldColDR.x()+1, 0});
101 for (; 102 for (;
102 (it != std::end(rightCollidables_) && 103 (it != std::end(rightCollidables_) &&
@@ -106,9 +107,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
106 newColUL.y() <= it->second.upper) { 107 newColUL.y() <= it->second.upper) {
107 int colliderSpriteId = std::get<1>(it->first); 108 int colliderSpriteId = std::get<1>(it->first);
108 Sprite& collider = game_.getSprite(colliderSpriteId); 109 Sprite& collider = game_.getSprite(colliderSpriteId);
109 result.horiz.blocked = collider.solid; 110 horizBlocked = collider.solid;
110 result.horiz.dir = Direction::right; 111 result.dir = Direction::right;
111 result.horiz.colliderSprite = colliderSpriteId; 112 result.colliders.push_back(colliderSpriteId);
112 113
113 break; 114 break;
114 } 115 }
@@ -121,23 +122,23 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
121 newColUL.x() >= 0) { 122 newColUL.x() >= 0) {
122 for (int y = newTileUL.y(); y <= newTileDR.y(); y++) { 123 for (int y = newTileUL.y(); y <= newTileDR.y(); y++) {
123 if (map.isBlocked(newTileUL.x(), y)) { 124 if (map.isBlocked(newTileUL.x(), y)) {
124 result.horiz.blocked = true; 125 horizBlocked = true;
125 result.horiz.dir = Direction::left; 126 result.dir = Direction::left;
126 127
127 break; 128 break;
128 } 129 }
129 } 130 }
130 } 131 }
131 132
132 if (!result.horiz.blocked && enclosureZone) { 133 if (!horizBlocked && enclosureZone) {
133 if (oldColUL.x() >= enclosureZone->ul.x() && 134 if (oldColUL.x() >= enclosureZone->ul.x() &&
134 newColUL.x() < enclosureZone->ul.x()) { 135 newColUL.x() < enclosureZone->ul.x()) {
135 result.horiz.blocked = true; 136 horizBlocked = true;
136 result.horiz.dir = Direction::left; 137 result.dir = Direction::left;
137 } 138 }
138 } 139 }
139 140
140 if (!result.horiz.blocked) { 141 if (!horizBlocked) {
141 auto it = leftCollidables_.lower_bound({oldColUL.x()-1, INT_MAX}); 142 auto it = leftCollidables_.lower_bound({oldColUL.x()-1, INT_MAX});
142 for (; 143 for (;
143 (it != std::end(leftCollidables_) && 144 (it != std::end(leftCollidables_) &&
@@ -147,9 +148,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
147 newColUL.y() <= it->second.upper) { 148 newColUL.y() <= it->second.upper) {
148 int colliderSpriteId = std::get<1>(it->first); 149 int colliderSpriteId = std::get<1>(it->first);
149 Sprite& collider = game_.getSprite(colliderSpriteId); 150 Sprite& collider = game_.getSprite(colliderSpriteId);
150 result.horiz.blocked = collider.solid; 151 horizBlocked = collider.solid;
151 result.horiz.dir = Direction::left; 152 result.dir = Direction::left;
152 result.horiz.colliderSprite = colliderSpriteId; 153 result.colliders.push_back(colliderSpriteId);
153 154
154 break; 155 break;
155 } 156 }
@@ -161,12 +162,14 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
161 // taken place (as long as it was not in fact blocked). 162 // taken place (as long as it was not in fact blocked).
162 vec2i effectiveCurLoc = curLoc; 163 vec2i effectiveCurLoc = curLoc;
163 vec2i vertMovement = newLoc; 164 vec2i vertMovement = newLoc;
164 if (result.horiz.blocked) { 165 if (horizBlocked) {
165 vertMovement.x() = curLoc.x(); 166 vertMovement.x() = curLoc.x();
166 } else { 167 } else {
167 effectiveCurLoc.x() = newLoc.x(); 168 effectiveCurLoc.x() = newLoc.x();
168 } 169 }
169 170
171 bool vertBlocked = false;
172
170 oldColUL = effectiveCurLoc + sprite.collisionOffset; 173 oldColUL = effectiveCurLoc + sprite.collisionOffset;
171 oldColDR = oldColUL + sprite.collisionSize - vec2i{1,1}; 174 oldColDR = oldColUL + sprite.collisionSize - vec2i{1,1};
172 newColUL = vertMovement + sprite.collisionOffset; 175 newColUL = vertMovement + sprite.collisionOffset;
@@ -182,23 +185,23 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
182 newColDR.y() < mapBounds.h()) { 185 newColDR.y() < mapBounds.h()) {
183 for (int x = newTileUL.x(); x <= newTileDR.x(); x++) { 186 for (int x = newTileUL.x(); x <= newTileDR.x(); x++) {
184 if (map.isBlocked(x, newTileDR.y())) { 187 if (map.isBlocked(x, newTileDR.y())) {
185 result.vert.blocked = true; 188 vertBlocked = true;
186 result.vert.dir = Direction::down; 189 result.dir = Direction::down;
187 190
188 break; 191 break;
189 } 192 }
190 } 193 }
191 } 194 }
192 195
193 if (!result.vert.blocked && enclosureZone) { 196 if (!vertBlocked && enclosureZone) {
194 if (oldColDR.y() <= enclosureZone->dr.y()-1 && 197 if (oldColDR.y() <= enclosureZone->dr.y()-1 &&
195 newColDR.y() > enclosureZone->dr.y()-1) { 198 newColDR.y() > enclosureZone->dr.y()-1) {
196 result.vert.blocked = true; 199 vertBlocked = true;
197 result.vert.dir = Direction::down; 200 result.dir = Direction::down;
198 } 201 }
199 } 202 }
200 203
201 if (!result.vert.blocked) { 204 if (!vertBlocked) {
202 auto it = downCollidables_.lower_bound({oldColDR.y()+1, 0}); 205 auto it = downCollidables_.lower_bound({oldColDR.y()+1, 0});
203 for (; 206 for (;
204 (it != std::end(downCollidables_) && 207 (it != std::end(downCollidables_) &&
@@ -208,9 +211,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
208 newColUL.x() <= it->second.upper) { 211 newColUL.x() <= it->second.upper) {
209 int colliderSpriteId = std::get<1>(it->first); 212 int colliderSpriteId = std::get<1>(it->first);
210 Sprite& collider = game_.getSprite(colliderSpriteId); 213 Sprite& collider = game_.getSprite(colliderSpriteId);
211 result.vert.blocked = collider.solid; 214 vertBlocked = collider.solid;
212 result.vert.dir = Direction::down; 215 result.dir = Direction::down;
213 result.vert.colliderSprite = colliderSpriteId; 216 result.colliders.push_back(colliderSpriteId);
214 217
215 break; 218 break;
216 } 219 }
@@ -223,23 +226,23 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
223 newColUL.y() >= 0) { 226 newColUL.y() >= 0) {
224 for (int x = newTileUL.x(); x <= newTileDR.x(); x++) { 227 for (int x = newTileUL.x(); x <= newTileDR.x(); x++) {
225 if (map.isBlocked(x, newTileUL.y())) { 228 if (map.isBlocked(x, newTileUL.y())) {
226 result.vert.blocked = true; 229 vertBlocked = true;
227 result.vert.dir = Direction::up; 230 result.dir = Direction::up;
228 231
229 break; 232 break;
230 } 233 }
231 } 234 }
232 } 235 }
233 236
234 if (!result.vert.blocked && enclosureZone) { 237 if (!vertBlocked && enclosureZone) {
235 if (oldColUL.y() >= enclosureZone->ul.y() && 238 if (oldColUL.y() >= enclosureZone->ul.y() &&
236 newColUL.y() < enclosureZone->ul.y()) { 239 newColUL.y() < enclosureZone->ul.y()) {
237 result.vert.blocked = true; 240 vertBlocked = true;
238 result.vert.dir = Direction::up; 241 result.dir = Direction::up;
239 } 242 }
240 } 243 }
241 244
242 if (!result.vert.blocked) { 245 if (!vertBlocked) {
243 auto it = upCollidables_.lower_bound({oldColUL.y()-1, INT_MAX}); 246 auto it = upCollidables_.lower_bound({oldColUL.y()-1, INT_MAX});
244 for (; 247 for (;
245 (it != std::end(upCollidables_) && 248 (it != std::end(upCollidables_) &&
@@ -249,9 +252,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
249 newColUL.x() <= it->second.upper) { 252 newColUL.x() <= it->second.upper) {
250 int colliderSpriteId = std::get<1>(it->first); 253 int colliderSpriteId = std::get<1>(it->first);
251 Sprite& collider = game_.getSprite(colliderSpriteId); 254 Sprite& collider = game_.getSprite(colliderSpriteId);
252 result.vert.blocked = collider.solid; 255 vertBlocked = collider.solid;
253 result.vert.dir = Direction::up; 256 result.dir = Direction::up;
254 result.vert.colliderSprite = colliderSpriteId; 257 result.colliders.push_back(colliderSpriteId);
255 258
256 break; 259 break;
257 } 260 }
@@ -259,6 +262,13 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2
259 } 262 }
260 } 263 }
261 264
265 result.adjustedLoc = vertMovement;
266 if (vertBlocked) {
267 result.adjustedLoc.y() = effectiveCurLoc.y();
268 }
269
270 result.blocked = horizBlocked || vertBlocked;
271
262 return result; 272 return result;
263} 273}
264 274