Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crouching/sneaking with shift, move slower and not fall of ledges #4

Open
satoshinm opened this issue Apr 2, 2017 · 2 comments
Open
Labels
Milestone

Comments

@satoshinm
Copy link
Owner

Allow moving more carefully when holding down the "shift key", aka crouching or sneaking. Slows down movement and prevents falling off an edge of the blocks. Important for survival.

@satoshinm
Copy link
Owner Author

satoshinm commented May 5, 2017

Gravity is implemented in handle_movement(), if not flying then dy each time step, and drop down unless colliding vertically with a block:

        if (g->flying) {
            dy = 0;
        }
        else {
            dy -= ut * 25;
            dy = MAX(dy, -250);
        }
         s->x += vx;
         s->y += vy + dy * ut;
         s->z += vz;
         if (collide(2, &s->x, &s->y, &s->z)) {
             dy = 0;

collide() clamps its input coordinates on output to right up to a block. Returns 1 if y collided, else 0. If returns 0, then the player is falling. This is where crouching could be implemented, canceling the x/z movement:

             dy = 0;
+        } else {
+            if (crouching && !g->flying) {
+                s->y -= vy + dy * ut; // don't fall off ledges
+                // TODO: allow sliding along edges in one axis
+                s->x -= vx;
+                s->z -= vz;

but this doesn't let the player "slide" along the edges while not falling off. Ideally want to allow movement in the direction that wouldn't cause the player to fall off. They should be able to slide in either direction, as long as it doesn't fall (no flying). Stuck on this, my half-baked solutions either allow floating or no sliding:

--- a/src/main.c
+++ b/src/main.c
@@ -2942,9 +2942,9 @@ void handle_movement(double dt) {
     }
     float vx, vy = 0, vz;
     get_motion_vector(g->flying, sz, sx, s->rx, s->ry, &vx, &vy, &vz);
+    int jumping = glfwGetKey(g->window, CRAFT_KEY_JUMP) || touch_jump;
+    int crouching = glfwGetKey(g->window, CRAFT_KEY_CROUCH);
     if (!g->typing) {
-        int jumping = glfwGetKey(g->window, CRAFT_KEY_JUMP) || touch_jump;
-        int crouching = glfwGetKey(g->window, CRAFT_KEY_CROUCH);
 
         if (g->gamepad_connected != -1) {
             if (g->gamepad_state.digitalButton[GAMEPAD_A]) jumping = 1;
@@ -2986,6 +2986,7 @@ void handle_movement(double dt) {
     vx = vx * ut * speed;
     vy = vy * ut * speed;
     vz = vz * ut * speed;
+
     for (int i = 0; i < step; i++) {
         if (g->flying) {
             dy = 0;
@@ -2994,11 +2995,27 @@ void handle_movement(double dt) {
             dy -= ut * 25;
             dy = MAX(dy, -250);
         }
-        s->x += vx;
-        s->y += vy + dy * ut;
-        s->z += vz;
-        if (collide(2, &s->x, &s->y, &s->z)) {
+        float tx = s->x + vx;
+        float ty = s->y + vy + dy * ut;
+        float tz = s->z + vz;
+
+        if (collide(2, &tx, &ty, &tz)) {
             dy = 0;
+            s->x = tx;
+            s->y = ty;
+            s->z = tz;
+        } else {
+            // would fall
+            if (crouching && !g->flying) {
+                if (sx != 0) s->x = tx;
+                //s->y = ty;
+                if (sz != 0) s->z = tz;
+                printf("x %f, y %f, z %f\n", s->x-tx, s->y-ty, s->z-tz);
+            } else {
+                s->x = tx;
+                s->y = ty;
+                s->z = tz;
+            }
         }
     }
     if (s->y < 0) {

@satoshinm
Copy link
Owner Author

Introduces more problems than it solves, so reverted this feature (but kept the small refactoring changes surrounding it). When fixing again, make sure to avoid #181 crouching allows hovering in midair while falling and #180 crouching doesn't allow sliding along edges. Maybe there is some simpler implementation to avoid these problems I am missing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant