From ef17fecfb22ccacbf098f6869ffaf644a1a627d6 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Sat, 6 Feb 2021 12:15:07 -0500 Subject: Added collidable object cache --- src/transform_system.cpp | 79 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 18 deletions(-) (limited to 'src/transform_system.cpp') 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) { spritesByY_.emplace(loc.y(), spriteId); } +void TransformSystem::setUpCollision(int spriteId, vec2i offset, vec2i size) { + Sprite& sprite = game_.getSprite(spriteId); + sprite.collidable = true; + sprite.collisionOffset = offset; + sprite.collisionSize = size; + + addCollidable(spriteId); +} + void TransformSystem::moveSprite(int spriteId, vec2i newLoc) { Sprite& sprite = game_.getSprite(spriteId); + if (sprite.collidable) { + removeCollidable(spriteId); + } + bool changedY = (sprite.loc.y() != newLoc.y()); if (changedY) { spritesByY_.erase(std::make_tuple(sprite.loc.y(), spriteId)); @@ -18,6 +31,9 @@ void TransformSystem::moveSprite(int spriteId, vec2i newLoc) { if (changedY) { spritesByY_.emplace(newLoc.y(), spriteId); } + if (sprite.collidable) { + addCollidable(spriteId); + } } CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Direction dir) { @@ -28,17 +44,20 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Dire const Map& map = game_.getMap(); bool blocked = false; - const vec2i UL_COL_BOX = { 8, 8 }; - const vec2i DR_COL_BOX = { 4, 0 }; - vec2i oldColPosUL = (sprite.loc - UL_COL_BOX) / map.getTileSize(); - vec2i newColPosUL = (newLoc - UL_COL_BOX) / map.getTileSize(); - vec2i oldColPosDR = (sprite.loc + DR_COL_BOX) / map.getTileSize(); - vec2i newColPosDR = (newLoc + DR_COL_BOX) / map.getTileSize(); + vec2i oldColUL = sprite.loc + sprite.collisionOffset; + vec2i oldColDR = oldColUL + sprite.collisionSize; + vec2i newColUL = newLoc + sprite.collisionOffset; + vec2i newColDR = newColUL + sprite.collisionSize; + + vec2i oldTileUL = oldColUL / map.getTileSize(); + vec2i newTileUL = newColUL / map.getTileSize(); + vec2i oldTileDR = oldColDR / map.getTileSize(); + vec2i newTileDR = newColDR / map.getTileSize(); if (dirHasDir(sprite.dir, Direction::right) && - newColPosDR.x() > oldColPosDR.x()) { - for (int y = newColPosUL.y(); y <= newColPosDR.y(); y++) { - if (map.isBlocked(newColPosDR.x(), y)) { + newTileDR.x() > oldTileDR.x()) { + for (int y = newTileUL.y(); y <= newTileDR.y(); y++) { + if (map.isBlocked(newTileDR.x(), y)) { result.horiz.blocked = true; result.horiz.dir = Direction::right; @@ -48,9 +67,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Dire } if (dirHasDir(sprite.dir, Direction::left) && - newColPosUL.x() < oldColPosUL.x()) { - for (int y = newColPosUL.y(); y <= newColPosDR.y(); y++) { - if (map.isBlocked(newColPosUL.x(), y)) { + newTileUL.x() < oldTileUL.x()) { + for (int y = newTileUL.y(); y <= newTileDR.y(); y++) { + if (map.isBlocked(newTileUL.x(), y)) { result.horiz.blocked = true; result.horiz.dir = Direction::left; @@ -60,9 +79,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Dire } if (dirHasDir(sprite.dir, Direction::down) && - newColPosDR.y() > oldColPosDR.y()) { - for (int x = newColPosUL.x(); x <= newColPosDR.x(); x++) { - if (map.isBlocked(x, newColPosDR.y())) { + newTileDR.y() > oldTileDR.y()) { + for (int x = newTileUL.x(); x <= newTileDR.x(); x++) { + if (map.isBlocked(x, newTileDR.y())) { result.vert.blocked = true; result.vert.dir = Direction::down; @@ -72,9 +91,9 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Dire } if (dirHasDir(sprite.dir, Direction::up) && - newColPosUL.y() < oldColPosUL.y()) { - for (int x = newColPosUL.x(); x <= newColPosDR.x(); x++) { - if (map.isBlocked(x, newColPosUL.y())) { + newTileUL.y() < oldTileUL.y()) { + for (int x = newTileUL.x(); x <= newTileDR.x(); x++) { + if (map.isBlocked(x, newTileUL.y())) { result.vert.blocked = true; result.vert.dir = Direction::up; @@ -85,3 +104,27 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Dire return result; } + +void TransformSystem::addCollidable(int spriteId) { + Sprite& sprite = game_.getSprite(spriteId); + + vec2i colUL = sprite.loc + sprite.collisionOffset; + vec2i colDR = colUL + sprite.collisionSize; + + leftCollidables_.emplace(std::piecewise_construct, std::tie(colDR.x(), spriteId), std::tie(colUL.y(), colDR.y())); + rightCollidables_.emplace(std::piecewise_construct, std::tie(colUL.x(), spriteId), std::tie(colUL.y(), colDR.y())); + upCollidables_.emplace(std::piecewise_construct, std::tie(colDR.y(), spriteId), std::tie(colUL.x(), colDR.x())); + downCollidables_.emplace(std::piecewise_construct, std::tie(colUL.y(), spriteId), std::tie(colUL.x(), colDR.x())); +} + +void TransformSystem::removeCollidable(int spriteId) { + Sprite& sprite = game_.getSprite(spriteId); + + vec2i colUL = sprite.loc + sprite.collisionOffset; + vec2i colDR = colUL + sprite.collisionSize; + + leftCollidables_.erase({ colDR.x(), spriteId }); + rightCollidables_.erase({ colUL.x(), spriteId }); + upCollidables_.erase({ colDR.y(), spriteId }); + downCollidables_.erase({ colUL.y(), spriteId }); +} -- cgit 1.4.1