From 6726fb04c32d5454ba50f046a4b83432ea109459 Mon Sep 17 00:00:00 2001 From: outfrost Date: Mon, 21 Sep 2020 01:58:33 +0200 Subject: [PATCH] Resolve slides before crossing cell boundaries so we don't get stuck on corners --- src/game/player.c | 94 +++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 49 deletions(-) diff --git a/src/game/player.c b/src/game/player.c index 52d747f..a56cae9 100644 --- a/src/game/player.c +++ b/src/game/player.c @@ -82,9 +82,6 @@ static void movePlayer(Vector direction, float delta) { direction = clampMagnitude(direction, 1.0f); Vector displacement = scaleVector(direction, delta * movementSpeed); -//{ -//Vector displacement = scaleVector(direction, 0.006944f * movementSpeed * 1000.0f); - playerProjectedMovement->transform = playerCharacter->transform; Vector initialPosition = translationOf(playerCharacter->transform); @@ -181,66 +178,65 @@ static void movePlayer(Vector direction, float delta) { distanceZp -= displacementToLimit.z; distanceZn -= displacementToLimit.z; - // Resolve slides and crossing cell boundaries - // in reverse order to direct movement limits, because - // we only want to cross the closest cell boundary. - if (reachedZn) { - if (obstacle & OBSTACLE_ZN) { - float dx = clamp(displacement.x, distanceXn, distanceXp); - position.x += dx; - displacement = scaleVector(displacement, 1.0f - (dx / displacement.x)); + // Slide along obstacles + if ((reachedXp && obstacle & OBSTACLE_XP) + || (reachedXn && obstacle & OBSTACLE_XN)) + { + float dz = displacement.z; + if (dz > distanceZp) { + dz = distanceZp; + reachedZp = true; } - else { - location.z -= 1; - enteredNewCell = true; + if (dz < distanceZn) { + dz = distanceZn; + reachedZn = true; } + position.z += dz; + displacement = scaleVector(displacement, 1.0f - (dz / displacement.z)); } - if (reachedZp) { - if (obstacle & OBSTACLE_ZP) { - float dx = clamp(displacement.x, distanceXn, distanceXp); - position.x += dx; - displacement = scaleVector(displacement, 1.0f - (dx / displacement.x)); + if ((reachedZp && obstacle & OBSTACLE_ZP) + || (reachedZn && obstacle & OBSTACLE_ZN)) + { + float dx = displacement.x; + if (dx > distanceXp) { + dx = distanceXp; + reachedXp = true; } - else if (!enteredNewCell) { - location.z += 1; - enteredNewCell = true; + if (dx < distanceXn) { + dx = distanceXn; + reachedXn = true; } + position.x += dx; + displacement = scaleVector(displacement, 1.0f - (dx / displacement.x)); } - if (reachedXn) { - if (obstacle & OBSTACLE_XN) { - float dz = clamp(displacement.z, distanceZn, distanceZp); - position.z += dz; - displacement = scaleVector(displacement, 1.0f - (dz / displacement.z)); - } - else if (!enteredNewCell) { - location.x -= 1; - enteredNewCell = true; - } + // Resolve crossing cell boundaries + // in reverse order to direct movement limits, because + // we only want to cross the closest cell boundary. + if (reachedZn && !(obstacle & OBSTACLE_ZN)) { + // Enter new grid cell + location.z -= 1; + enteredNewCell = true; } - if (reachedXp) { - if (obstacle & OBSTACLE_XP) { - // Slide - float dz = clamp(displacement.z, distanceZn, distanceZp); - position.z += dz; - displacement = scaleVector(displacement, 1.0f - (dz / displacement.z)); - } - else if (!enteredNewCell) { - // Enter new grid cell - location.x += 1; - enteredNewCell = true; - } + if (!enteredNewCell && reachedZp && !(obstacle & OBSTACLE_ZP)) { + location.z += 1; + enteredNewCell = true; } - } - //translate(&playerProjectedMovement->transform, subtractVectors(position, initialPosition)); - translate(&playerCharacter->transform, subtractVectors(position, initialPosition)); -//} + if (!enteredNewCell && reachedXn && !(obstacle & OBSTACLE_XN)) { + location.x -= 1; + enteredNewCell = true; + } + if (!enteredNewCell && reachedXp && !(obstacle & OBSTACLE_XP)) { + location.x += 1; + enteredNewCell = true; + } + } - //translate(&playerCharacter->transform, displacement); + translate(&playerCharacter->transform, subtractVectors(position, initialPosition)); } static Vector worldMovementDirection(float x, float y) { -- 2.44.0