diff options
author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2021-03-11 16:06:19 -0500 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2021-03-11 17:33:15 -0500 |
commit | eb9fa5020317a44f17cc4906c4c1c6fe55700d3e (patch) | |
tree | e4cb67d97818e06d974d0fca987dd76f25affdf9 /src/transform_system.cpp | |
parent | 4c29543e44deb7a327b21b0af6a85a92e83ff103 (diff) | |
download | tanetane-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.cpp | 84 |
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 | ||