Reputation: 21
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
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