summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2021-03-11 17:29:02 -0500
committerStar Rauchenberger <fefferburbia@gmail.com>2021-03-11 17:33:15 -0500
commita6d1ded1a41d0f461bf340a33e21fa896ce9da66 (patch)
tree9ddaf30031b1ffe2aa8be9b412038c99a6b879d7
parenteb9fa5020317a44f17cc4906c4c1c6fe55700d3e (diff)
downloadtanetane-a6d1ded1a41d0f461bf340a33e21fa896ce9da66.tar.gz
tanetane-a6d1ded1a41d0f461bf340a33e21fa896ce9da66.tar.bz2
tanetane-a6d1ded1a41d0f461bf340a33e21fa896ce9da66.zip
Added sliding around solid tiles
#3
-rw-r--r--src/character_system.cpp2
-rw-r--r--src/main.cpp1
-rw-r--r--src/sprite.h1
-rw-r--r--src/transform_system.cpp70
-rw-r--r--src/transform_system.h7
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
5bool checkCollisionOptionsContains(CheckCollisionOptions options, CheckCollisionOptions value) {
6 return (static_cast<int>(options) & static_cast<int>(value)) != 0;
7}
8
5void TransformSystem::initSprite(int spriteId, vec2i loc, SpriteLayer layer) { 9void 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
50CollisionResult TransformSystem::checkCollision(int spriteId, vec2i curLoc, vec2i newLoc, Direction dir) { 54CollisionResult 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
24enum class CheckCollisionOptions {
25 None = 0,
26 AllowSliding = 1 << 0
27};
28
24class TransformSystem : public System { 29class TransformSystem : public System {
25public: 30public:
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