ConvexProjects
ConvexProjects

Reputation: 21

Falling animation plays throughout the whole jump?

It's a pretty simple problem. When I jump in my game, there are two animations. One for rising and one for falling. However, when jumping while moving left or right, it only plays the falling animation.

CREATE:

// Constants
moveSpeed = 5;
acceleration = 1.6;
deceleration = 1;
jumpPower = 12;
grav = 0.5;
maxFallSpeed = 50;

// Initialize variables
hsp = 0;
vsp = 0;
canJump = true;
newSprite = spr_idle_strip1;
image_xscale = 2;

STEP:

// Horizontal Movement
var moveInput = keyboard_check(vk_right) - keyboard_check(vk_left);

if (moveInput != 0) {
    // Accelerate towards the maximum speed
    hsp += moveInput * acceleration;
    hsp = clamp(hsp, -moveSpeed, moveSpeed); // Limit speed to the max speed

    // Set the sprite to running animation
    if (vsp == 0) {
        newSprite = spr_run_strip6;
    } else if (vsp <= 0) {
        newSprite = spr_freefall_strip2;
    } else if (vsp > 0 && !place_meeting(x, y + 1, obj_wall)) {
        newSprite = spr_jump_strip4;
    }
    // Mirror the sprite when moving left
    if (moveInput < 0) {
        image_xscale = -2;
    } else {
        image_xscale = 2;
    }
} else {
    // Decelerate when no movement input
    if (hsp != 0) {
        var dir = sign(hsp);
        hsp -= dir * deceleration;
        if (sign(hsp) != dir) {
            hsp = 0;
        }
    }

    if (place_meeting(x, y + 1, obj_wall)) {
        newSprite = spr_idle_strip1;
    } else if (vsp >= 0) {
        if (moveInput != 0) {
            newSprite = spr_freefall_strip2;
        } else if (moveInput == 0) {
            newSprite = spr_freefall_strip2;
        } else {
            newSprite = spr_jump_strip4;
        }
        // Reset the jump frame counter when falling
        jumpFrame = 0;
    } else {
        newSprite = spr_jump_strip4;
    }
}

// Applying Gravity
if (!place_meeting(x, y + 1, obj_wall)) {
    // If the player is not touching the ground, apply gravity
    vsp += grav;
    if (vsp > maxFallSpeed) {
        vsp = maxFallSpeed;
    }
    if (vsp > 0 && !place_meeting(x, y + 1, obj_wall)) {
        newSprite = spr_freefall_strip2;
    } else {
        // Player is jumping, update jumpFrame to animate the jump
        jumpFrame += 0.1;
        if (jumpFrame >= sprite_get_number(spr_jump_strip4)) {
            jumpFrame = sprite_get_number(spr_jump_strip4) - 1;
        }
    }
} else {
    // Player is on the ground, reset the jump frame counter
    jumpFrame = 0;
}

// Jumping
if (place_meeting(x, y + 1, obj_wall)) {
    canJump = true;
} else {
    canJump = false; // Cannot jump while not on a solid block
}

if (canJump and keyboard_check_pressed(vk_space)) {
    vsp = -jumpPower;
    canJump = false;
    newSprite = spr_jump_strip4;
    // Reset the jump frame counter
    jumpFrame = 0;
}

// Set the player's sprite
sprite_index = newSprite;

// Final Movement
if (place_meeting(x + hsp, y, obj_wall)) {
    while (!place_meeting(x + sign(hsp), y, obj_wall)) {
        x += sign(hsp);
    }
    hsp = 0;
}

x += hsp;

// Vertical Collision
if (place_meeting(x, y + vsp, obj_wall)) {
    while (!place_meeting(x, y + sign(vsp), obj_wall)) {
        y += sign(vsp);
    }
    vsp = 0;
}

y += vsp;

One of the things I've tried is using image_index, using a frame counter to update the jump animation frames, yet the images moved along too slow, and I had my struggles with image_speed.

ChatGPT wasn't helpful, and other solutions simply don't work.

I just want rising during a jump to play the spr_jump_strip4 animation, and spr_freefall_strip2 to play while falling.

Upvotes: 1

Views: 44

Answers (1)

Steven
Steven

Reputation: 2122

You say it only plays when moving left or right, so in your code logic, only the part within the if (moveInput != 0) and it's else statement is relevant. Because that decides if your character is moving or not.

From there, I can see that there's a difference between this code:

// Set the sprite to running animation
if (vsp == 0) {
    newSprite = spr_run_strip6;
} else if (vsp <= 0) {
    newSprite = spr_freefall_strip2;
} else if (vsp > 0 && !place_meeting(x, y + 1, obj_wall)) {
    newSprite = spr_jump_strip4;
}

and the code in your else statement of the condition:

if (place_meeting(x, y + 1, obj_wall)) {
    newSprite = spr_idle_strip1;
} else if (vsp >= 0) {
    if (moveInput != 0) {
        newSprite = spr_freefall_strip2;
    } else if (moveInput == 0) {
        newSprite = spr_freefall_strip2;
    } else {
        newSprite = spr_jump_strip4;
    }
    // Reset the jump frame counter when falling
    jumpFrame = 0;
} else {
    newSprite = spr_jump_strip4;
}

Since this is the else statement of (moveInput != 0), then moveInput is always 0, which means it'll always go through the spr_freefall_strip2 there.

Since these code blocks do basically the same thing, I recommend making them the same.

Or better yet, put them outside the moveInput != 0 condition and keep it one block of code, since the only thing related to it is a running sprite, which you can set seperately.

Upvotes: 2

Related Questions