diff options
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 | ||
