From a6d1ded1a41d0f461bf340a33e21fa896ce9da66 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Thu, 11 Mar 2021 17:29:02 -0500 Subject: Added sliding around solid tiles #3 --- src/transform_system.cpp | 70 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) (limited to 'src/transform_system.cpp') diff --git a/src/transform_system.cpp b/src/transform_system.cpp index a643255..825514f 100644 --- a/src/transform_system.cpp +++ b/src/transform_system.cpp @@ -2,6 +2,10 @@ #include "game.h" #include "map.h" +bool checkCollisionOptionsContains(CheckCollisionOptions options, CheckCollisionOptions value) { + return (static_cast(options) & static_cast(value)) != 0; +} + void TransformSystem::initSprite(int spriteId, vec2i loc, SpriteLayer layer) { Sprite& sprite = game_.getSprite(spriteId); sprite.loc = loc; @@ -47,7 +51,7 @@ void TransformSystem::moveSprite(int spriteId, vec2i newLoc) { } } -CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2i newLoc, Direction dir) { +CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2i newLoc, Direction dir, CheckCollisionOptions options) { CollisionResult result; Sprite& sprite = game_.getSprite(spriteId); @@ -87,6 +91,22 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 break; } } + + if (checkCollisionOptionsContains(options, CheckCollisionOptions::AllowSliding) && + sprite.sliding && + dir == Direction::right && + horizBlocked && + oldTileUL.y() != oldTileDR.y()) { + // If sliding is enabled for this sprite, check if we can slide + // either perpendicular direction. Because sliding can only happen + // if we were moving in a cardinal direction, we can use tail + // recursion and exit early. + if (!map.isBlocked(oldTileDR.x()+1, oldTileUL.y())) { + return checkCollision(spriteId, curLoc, curLoc - vec2i{0,1} * sprite.movementSpeed, Direction::up); + } else if (!map.isBlocked(oldTileDR.x()+1, oldTileDR.y())) { + return checkCollision(spriteId, curLoc, curLoc + vec2i{0,1} * sprite.movementSpeed, Direction::down); + } + } } if (!horizBlocked && enclosureZone) { @@ -128,6 +148,22 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 break; } } + + if (checkCollisionOptionsContains(options, CheckCollisionOptions::AllowSliding) && + sprite.sliding && + dir == Direction::left && + horizBlocked && + oldTileUL.y() != oldTileDR.y()) { + // If sliding is enabled for this sprite, check if we can slide + // either perpendicular direction. Because sliding can only happen + // if we were moving in a cardinal direction, we can use tail + // recursion and exit early. + if (!map.isBlocked(oldTileUL.x()-1, oldTileUL.y())) { + return checkCollision(spriteId, curLoc, curLoc - vec2i{0,1} * sprite.movementSpeed, Direction::up); + } else if (!map.isBlocked(oldTileUL.x()-1, oldTileDR.y())) { + return checkCollision(spriteId, curLoc, curLoc + vec2i{0,1} * sprite.movementSpeed, Direction::down); + } + } } if (!horizBlocked && enclosureZone) { @@ -191,6 +227,22 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 break; } } + + if (checkCollisionOptionsContains(options, CheckCollisionOptions::AllowSliding) && + sprite.sliding && + dir == Direction::down && + vertBlocked && + oldTileUL.x() != oldTileDR.x()) { + // If sliding is enabled for this sprite, check if we can slide + // either perpendicular direction. Because sliding can only happen + // if we were moving in a cardinal direction, we can use tail + // recursion and exit early. + if (!map.isBlocked(oldTileUL.x(), oldTileDR.y()+1)) { + return checkCollision(spriteId, curLoc, curLoc - vec2i{1,0} * sprite.movementSpeed, Direction::left); + } else if (!map.isBlocked(oldTileDR.x(), oldTileDR.y()+1)) { + return checkCollision(spriteId, curLoc, curLoc + vec2i{1,0} * sprite.movementSpeed, Direction::right); + } + } } if (!vertBlocked && enclosureZone) { @@ -232,6 +284,22 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 break; } } + + if (checkCollisionOptionsContains(options, CheckCollisionOptions::AllowSliding) && + sprite.sliding && + dir == Direction::up && + vertBlocked && + oldTileUL.x() != oldTileDR.x()) { + // If sliding is enabled for this sprite, check if we can slide + // either perpendicular direction. Because sliding can only happen + // if we were moving in a cardinal direction, we can use tail + // recursion and exit early. + if (!map.isBlocked(oldTileUL.x(), oldTileUL.y()-1)) { + return checkCollision(spriteId, curLoc, curLoc - vec2i{1,0} * sprite.movementSpeed, Direction::left); + } else if (!map.isBlocked(oldTileDR.x(), oldTileUL.y()-1)) { + return checkCollision(spriteId, curLoc, curLoc + vec2i{1,0} * sprite.movementSpeed, Direction::right); + } + } } if (!vertBlocked && enclosureZone) { -- cgit 1.4.1