diff options
| -rw-r--r-- | src/character_system.cpp | 2 | ||||
| -rw-r--r-- | src/main.cpp | 1 | ||||
| -rw-r--r-- | src/sprite.h | 1 | ||||
| -rw-r--r-- | src/transform_system.cpp | 70 | ||||
| -rw-r--r-- | src/transform_system.h | 7 |
5 files changed, 78 insertions, 3 deletions
| diff --git a/src/character_system.cpp b/src/character_system.cpp index 10cb06f..368505e 100644 --- a/src/character_system.cpp +++ b/src/character_system.cpp | |||
| @@ -153,7 +153,7 @@ void CharacterSystem::tick(double dt) { | |||
| 153 | pLoc += (unitVecInDirection(sprite.movementDir) * speed); | 153 | pLoc += (unitVecInDirection(sprite.movementDir) * speed); |
| 154 | 154 | ||
| 155 | // Check collision. | 155 | // Check collision. |
| 156 | CollisionResult collision = game_.getSystem<TransformSystem>().checkCollision(spriteId, sprite.loc, pLoc, sprite.movementDir); | 156 | CollisionResult collision = game_.getSystem<TransformSystem>().checkCollision(spriteId, sprite.loc, pLoc, sprite.movementDir, CheckCollisionOptions::AllowSliding); |
| 157 | 157 | ||
| 158 | if (!(collision.blocked && sprite.clipping)) { | 158 | if (!(collision.blocked && sprite.clipping)) { |
| 159 | pLoc = collision.adjustedLoc; | 159 | pLoc = collision.adjustedLoc; |
| diff --git a/src/main.cpp b/src/main.cpp index dcf96e5..b515891 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
| @@ -42,6 +42,7 @@ void loop(Renderer& renderer, std::mt19937& rng) { | |||
| 42 | game.getSprite(lucasSprite).player = true; | 42 | game.getSprite(lucasSprite).player = true; |
| 43 | game.getSprite(lucasSprite).controllable = true; | 43 | game.getSprite(lucasSprite).controllable = true; |
| 44 | game.getSprite(lucasSprite).persistent = true; | 44 | game.getSprite(lucasSprite).persistent = true; |
| 45 | game.getSprite(lucasSprite).sliding = true; | ||
| 45 | game.getSystem<CharacterSystem>().initSprite(lucasSprite, LUCAS_MOVEMENT_SPEED); | 46 | game.getSystem<CharacterSystem>().initSprite(lucasSprite, LUCAS_MOVEMENT_SPEED); |
| 46 | game.getSystem<CameraSystem>().setFollowingSprite(lucasSprite); | 47 | game.getSystem<CameraSystem>().setFollowingSprite(lucasSprite); |
| 47 | game.getSystem<CameraSystem>().unlockCamera(); | 48 | game.getSystem<CameraSystem>().unlockCamera(); |
| diff --git a/src/sprite.h b/src/sprite.h index f631652..413c20d 100644 --- a/src/sprite.h +++ b/src/sprite.h | |||
| @@ -83,6 +83,7 @@ public: | |||
| 83 | std::string walkthroughScript; | 83 | std::string walkthroughScript; |
| 84 | std::string bumpPlayerScript; | 84 | std::string bumpPlayerScript; |
| 85 | std::string enclosureZone; | 85 | std::string enclosureZone; |
| 86 | bool sliding = false; | ||
| 86 | 87 | ||
| 87 | // Animation (internals) | 88 | // Animation (internals) |
| 88 | bool isAnimated = false; | 89 | bool isAnimated = false; |
| 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 @@ | |||
| 2 | #include "game.h" | 2 | #include "game.h" |
| 3 | #include "map.h" | 3 | #include "map.h" |
| 4 | 4 | ||
| 5 | bool checkCollisionOptionsContains(CheckCollisionOptions options, CheckCollisionOptions value) { | ||
| 6 | return (static_cast<int>(options) & static_cast<int>(value)) != 0; | ||
| 7 | } | ||
| 8 | |||
| 5 | void TransformSystem::initSprite(int spriteId, vec2i loc, SpriteLayer layer) { | 9 | void TransformSystem::initSprite(int spriteId, vec2i loc, SpriteLayer layer) { |
| 6 | Sprite& sprite = game_.getSprite(spriteId); | 10 | Sprite& sprite = game_.getSprite(spriteId); |
| 7 | sprite.loc = loc; | 11 | sprite.loc = loc; |
| @@ -47,7 +51,7 @@ void TransformSystem::moveSprite(int spriteId, vec2i newLoc) { | |||
| 47 | } | 51 | } |
| 48 | } | 52 | } |
| 49 | 53 | ||
| 50 | CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2i newLoc, Direction dir) { | 54 | CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2i newLoc, Direction dir, CheckCollisionOptions options) { |
| 51 | CollisionResult result; | 55 | CollisionResult result; |
| 52 | 56 | ||
| 53 | Sprite& sprite = game_.getSprite(spriteId); | 57 | Sprite& sprite = game_.getSprite(spriteId); |
| @@ -87,6 +91,22 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 | |||
| 87 | break; | 91 | break; |
| 88 | } | 92 | } |
| 89 | } | 93 | } |
| 94 | |||
| 95 | if (checkCollisionOptionsContains(options, CheckCollisionOptions::AllowSliding) && | ||
| 96 | sprite.sliding && | ||
| 97 | dir == Direction::right && | ||
| 98 | horizBlocked && | ||
| 99 | oldTileUL.y() != oldTileDR.y()) { | ||
| 100 | // If sliding is enabled for this sprite, check if we can slide | ||
| 101 | // either perpendicular direction. Because sliding can only happen | ||
| 102 | // if we were moving in a cardinal direction, we can use tail | ||
| 103 | // recursion and exit early. | ||
| 104 | if (!map.isBlocked(oldTileDR.x()+1, oldTileUL.y())) { | ||
| 105 | return checkCollision(spriteId, curLoc, curLoc - vec2i{0,1} * sprite.movementSpeed, Direction::up); | ||
| 106 | } else if (!map.isBlocked(oldTileDR.x()+1, oldTileDR.y())) { | ||
| 107 | return checkCollision(spriteId, curLoc, curLoc + vec2i{0,1} * sprite.movementSpeed, Direction::down); | ||
| 108 | } | ||
| 109 | } | ||
| 90 | } | 110 | } |
| 91 | 111 | ||
| 92 | if (!horizBlocked && enclosureZone) { | 112 | if (!horizBlocked && enclosureZone) { |
| @@ -128,6 +148,22 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 | |||
| 128 | break; | 148 | break; |
| 129 | } | 149 | } |
| 130 | } | 150 | } |
| 151 | |||
| 152 | if (checkCollisionOptionsContains(options, CheckCollisionOptions::AllowSliding) && | ||
| 153 | sprite.sliding && | ||
| 154 | dir == Direction::left && | ||
| 155 | horizBlocked && | ||
| 156 | oldTileUL.y() != oldTileDR.y()) { | ||
| 157 | // If sliding is enabled for this sprite, check if we can slide | ||
| 158 | // either perpendicular direction. Because sliding can only happen | ||
| 159 | // if we were moving in a cardinal direction, we can use tail | ||
| 160 | // recursion and exit early. | ||
| 161 | if (!map.isBlocked(oldTileUL.x()-1, oldTileUL.y())) { | ||
| 162 | return checkCollision(spriteId, curLoc, curLoc - vec2i{0,1} * sprite.movementSpeed, Direction::up); | ||
| 163 | } else if (!map.isBlocked(oldTileUL.x()-1, oldTileDR.y())) { | ||
| 164 | return checkCollision(spriteId, curLoc, curLoc + vec2i{0,1} * sprite.movementSpeed, Direction::down); | ||
| 165 | } | ||
| 166 | } | ||
| 131 | } | 167 | } |
| 132 | 168 | ||
| 133 | if (!horizBlocked && enclosureZone) { | 169 | if (!horizBlocked && enclosureZone) { |
| @@ -191,6 +227,22 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 | |||
| 191 | break; | 227 | break; |
| 192 | } | 228 | } |
| 193 | } | 229 | } |
| 230 | |||
| 231 | if (checkCollisionOptionsContains(options, CheckCollisionOptions::AllowSliding) && | ||
| 232 | sprite.sliding && | ||
| 233 | dir == Direction::down && | ||
| 234 | vertBlocked && | ||
| 235 | oldTileUL.x() != oldTileDR.x()) { | ||
| 236 | // If sliding is enabled for this sprite, check if we can slide | ||
| 237 | // either perpendicular direction. Because sliding can only happen | ||
| 238 | // if we were moving in a cardinal direction, we can use tail | ||
| 239 | // recursion and exit early. | ||
| 240 | if (!map.isBlocked(oldTileUL.x(), oldTileDR.y()+1)) { | ||
| 241 | return checkCollision(spriteId, curLoc, curLoc - vec2i{1,0} * sprite.movementSpeed, Direction::left); | ||
| 242 | } else if (!map.isBlocked(oldTileDR.x(), oldTileDR.y()+1)) { | ||
| 243 | return checkCollision(spriteId, curLoc, curLoc + vec2i{1,0} * sprite.movementSpeed, Direction::right); | ||
| 244 | } | ||
| 245 | } | ||
| 194 | } | 246 | } |
| 195 | 247 | ||
| 196 | if (!vertBlocked && enclosureZone) { | 248 | if (!vertBlocked && enclosureZone) { |
| @@ -232,6 +284,22 @@ CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2 | |||
| 232 | break; | 284 | break; |
| 233 | } | 285 | } |
| 234 | } | 286 | } |
| 287 | |||
| 288 | if (checkCollisionOptionsContains(options, CheckCollisionOptions::AllowSliding) && | ||
| 289 | sprite.sliding && | ||
| 290 | dir == Direction::up && | ||
| 291 | vertBlocked && | ||
| 292 | oldTileUL.x() != oldTileDR.x()) { | ||
| 293 | // If sliding is enabled for this sprite, check if we can slide | ||
| 294 | // either perpendicular direction. Because sliding can only happen | ||
| 295 | // if we were moving in a cardinal direction, we can use tail | ||
| 296 | // recursion and exit early. | ||
| 297 | if (!map.isBlocked(oldTileUL.x(), oldTileUL.y()-1)) { | ||
| 298 | return checkCollision(spriteId, curLoc, curLoc - vec2i{1,0} * sprite.movementSpeed, Direction::left); | ||
| 299 | } else if (!map.isBlocked(oldTileDR.x(), oldTileUL.y()-1)) { | ||
| 300 | return checkCollision(spriteId, curLoc, curLoc + vec2i{1,0} * sprite.movementSpeed, Direction::right); | ||
| 301 | } | ||
| 302 | } | ||
| 235 | } | 303 | } |
| 236 | 304 | ||
| 237 | if (!vertBlocked && enclosureZone) { | 305 | if (!vertBlocked && enclosureZone) { |
| diff --git a/src/transform_system.h b/src/transform_system.h index 476b8d8..03f391a 100644 --- a/src/transform_system.h +++ b/src/transform_system.h | |||
| @@ -21,6 +21,11 @@ struct CollisionResult { | |||
| 21 | vec2i adjustedLoc; | 21 | vec2i adjustedLoc; |
| 22 | }; | 22 | }; |
| 23 | 23 | ||
| 24 | enum class CheckCollisionOptions { | ||
| 25 | None = 0, | ||
| 26 | AllowSliding = 1 << 0 | ||
| 27 | }; | ||
| 28 | |||
| 24 | class TransformSystem : public System { | 29 | class TransformSystem : public System { |
| 25 | public: | 30 | public: |
| 26 | 31 | ||
| @@ -42,7 +47,7 @@ public: | |||
| 42 | }); | 47 | }); |
| 43 | } | 48 | } |
| 44 | 49 | ||
| 45 | CollisionResult checkCollision(int spriteId, vec2i curLoc, vec2i newLoc, Direction dir); | 50 | CollisionResult checkCollision(int spriteId, vec2i curLoc, vec2i newLoc, Direction dir, CheckCollisionOptions options = CheckCollisionOptions::None); |
| 46 | 51 | ||
| 47 | CharacterMedium getMediumAtPosition(int spriteId, vec2i newLoc); | 52 | CharacterMedium getMediumAtPosition(int spriteId, vec2i newLoc); |
| 48 | 53 | ||
