From eb9fa5020317a44f17cc4906c4c1c6fe55700d3e Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Thu, 11 Mar 2021 16:06:19 -0500 Subject: 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. --- src/transform_system.cpp | 84 +++++++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 37 deletions(-) (limited to 'src/transform_system.cpp') 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 // First check horizontal movement only. vec2i horizMovement = { newLoc.x(), curLoc.y() }; + bool horizBlocked = false; vec2i oldColUL = curLoc + sprite.collisionOffset; vec2i oldColDR = oldColUL + sprite.collisionSize - vec2i{1,1}; @@ -80,23 +81,23 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 newColDR.x() < mapBounds.w()) { for (int y = newTileUL.y(); y <= newTileDR.y(); y++) { if (map.isBlocked(newTileDR.x(), y)) { - result.horiz.blocked = true; - result.horiz.dir = Direction::right; + horizBlocked = true; + result.dir = Direction::right; break; } } } - if (!result.horiz.blocked && enclosureZone) { + if (!horizBlocked && enclosureZone) { if (oldColDR.x() <= enclosureZone->dr.x()-1 && newColDR.x() > enclosureZone->dr.x()-1) { - result.horiz.blocked = true; - result.horiz.dir = Direction::right; + horizBlocked = true; + result.dir = Direction::right; } } - if (!result.horiz.blocked) { + if (!horizBlocked) { auto it = rightCollidables_.lower_bound({oldColDR.x()+1, 0}); for (; (it != std::end(rightCollidables_) && @@ -106,9 +107,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 newColUL.y() <= it->second.upper) { int colliderSpriteId = std::get<1>(it->first); Sprite& collider = game_.getSprite(colliderSpriteId); - result.horiz.blocked = collider.solid; - result.horiz.dir = Direction::right; - result.horiz.colliderSprite = colliderSpriteId; + horizBlocked = collider.solid; + result.dir = Direction::right; + result.colliders.push_back(colliderSpriteId); break; } @@ -121,23 +122,23 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 newColUL.x() >= 0) { for (int y = newTileUL.y(); y <= newTileDR.y(); y++) { if (map.isBlocked(newTileUL.x(), y)) { - result.horiz.blocked = true; - result.horiz.dir = Direction::left; + horizBlocked = true; + result.dir = Direction::left; break; } } } - if (!result.horiz.blocked && enclosureZone) { + if (!horizBlocked && enclosureZone) { if (oldColUL.x() >= enclosureZone->ul.x() && newColUL.x() < enclosureZone->ul.x()) { - result.horiz.blocked = true; - result.horiz.dir = Direction::left; + horizBlocked = true; + result.dir = Direction::left; } } - if (!result.horiz.blocked) { + if (!horizBlocked) { auto it = leftCollidables_.lower_bound({oldColUL.x()-1, INT_MAX}); for (; (it != std::end(leftCollidables_) && @@ -147,9 +148,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 newColUL.y() <= it->second.upper) { int colliderSpriteId = std::get<1>(it->first); Sprite& collider = game_.getSprite(colliderSpriteId); - result.horiz.blocked = collider.solid; - result.horiz.dir = Direction::left; - result.horiz.colliderSprite = colliderSpriteId; + horizBlocked = collider.solid; + result.dir = Direction::left; + result.colliders.push_back(colliderSpriteId); break; } @@ -161,12 +162,14 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 // taken place (as long as it was not in fact blocked). vec2i effectiveCurLoc = curLoc; vec2i vertMovement = newLoc; - if (result.horiz.blocked) { + if (horizBlocked) { vertMovement.x() = curLoc.x(); } else { effectiveCurLoc.x() = newLoc.x(); } + bool vertBlocked = false; + oldColUL = effectiveCurLoc + sprite.collisionOffset; oldColDR = oldColUL + sprite.collisionSize - vec2i{1,1}; newColUL = vertMovement + sprite.collisionOffset; @@ -182,23 +185,23 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 newColDR.y() < mapBounds.h()) { for (int x = newTileUL.x(); x <= newTileDR.x(); x++) { if (map.isBlocked(x, newTileDR.y())) { - result.vert.blocked = true; - result.vert.dir = Direction::down; + vertBlocked = true; + result.dir = Direction::down; break; } } } - if (!result.vert.blocked && enclosureZone) { + if (!vertBlocked && enclosureZone) { if (oldColDR.y() <= enclosureZone->dr.y()-1 && newColDR.y() > enclosureZone->dr.y()-1) { - result.vert.blocked = true; - result.vert.dir = Direction::down; + vertBlocked = true; + result.dir = Direction::down; } } - if (!result.vert.blocked) { + if (!vertBlocked) { auto it = downCollidables_.lower_bound({oldColDR.y()+1, 0}); for (; (it != std::end(downCollidables_) && @@ -208,9 +211,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 newColUL.x() <= it->second.upper) { int colliderSpriteId = std::get<1>(it->first); Sprite& collider = game_.getSprite(colliderSpriteId); - result.vert.blocked = collider.solid; - result.vert.dir = Direction::down; - result.vert.colliderSprite = colliderSpriteId; + vertBlocked = collider.solid; + result.dir = Direction::down; + result.colliders.push_back(colliderSpriteId); break; } @@ -223,23 +226,23 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 newColUL.y() >= 0) { for (int x = newTileUL.x(); x <= newTileDR.x(); x++) { if (map.isBlocked(x, newTileUL.y())) { - result.vert.blocked = true; - result.vert.dir = Direction::up; + vertBlocked = true; + result.dir = Direction::up; break; } } } - if (!result.vert.blocked && enclosureZone) { + if (!vertBlocked && enclosureZone) { if (oldColUL.y() >= enclosureZone->ul.y() && newColUL.y() < enclosureZone->ul.y()) { - result.vert.blocked = true; - result.vert.dir = Direction::up; + vertBlocked = true; + result.dir = Direction::up; } } - if (!result.vert.blocked) { + if (!vertBlocked) { auto it = upCollidables_.lower_bound({oldColUL.y()-1, INT_MAX}); for (; (it != std::end(upCollidables_) && @@ -249,9 +252,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 newColUL.x() <= it->second.upper) { int colliderSpriteId = std::get<1>(it->first); Sprite& collider = game_.getSprite(colliderSpriteId); - result.vert.blocked = collider.solid; - result.vert.dir = Direction::up; - result.vert.colliderSprite = colliderSpriteId; + vertBlocked = collider.solid; + result.dir = Direction::up; + result.colliders.push_back(colliderSpriteId); break; } @@ -259,6 +262,13 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 } } + result.adjustedLoc = vertMovement; + if (vertBlocked) { + result.adjustedLoc.y() = effectiveCurLoc.y(); + } + + result.blocked = horizBlocked || vertBlocked; + return result; } -- cgit 1.4.1