game-developmentgame-maker-studio-2game-maker-language

Jumping animation with landing and jumping sprites


I have 3 sprites that I want to make a jumping animation with:

spr_conejo_idle - 2 frames
spr_conejo_airbourne_up - 5 frames (4 for the jump and the last one frozen while vsp < 0)
spr_conejo_airbourne_down - 4 frames (1 for when vsp > 0 and the last 3 for the landing)

I'm trying to make it so that when the object jumps (vsp > 0), set the spr_conejo_airbourne_up sprite and keep the last frame frozen until it starts falling (vsp =< 0). when it starts falling, the sprite should be spr_conejo_airbourne_down which I want to freeze on the first frame until it vertically collides with a wall object, which will unfreeze the sprite, showing the landing animation, and finally the idle one.

What I tried:

CREATE EVENT

hp = 1;
hsp = 0;
vsp = 0;
grv = 0.3;
maxIdle = 360;
onFloor = true;
hitfrom = 0;
size = 1;

STEP EVENT

vsp += grv;

//time until next jump
maxIdle--;


if (place_meeting(x,y+1,obj_wall)){
    onFloor = true;
}
else {
    onFloor = false;
}

//if obj is on floor and time until next jump =< 0, jump
if (onFloor){
    if (maxIdle <= 0){
        maxIdle = random_range(60, 360);
        vsp = -6;
        onFloor = false;
        hsp = random_range(-3,3);
    }
}

//if jumping
if(!onFloor){
    // if going upwards
    if (sign(vsp) < 0) {
        //show jumping animation (will freeze on the Animation End event)
        image_speed = 1;
        sprite_index = spr_conejo_airbourne_up;
    }
    // if falling
    else {
        //freeze frame until on ground
        image_speed = 0;
        sprite_index = spr_conejo_airbourne_down;
    }
}
//if on ground
else{
    //continue animation (should trigger animation end event if sprite is airboune down, and change to idle)
    image_speed = 1;
    vsp = 0;
    hsp = 0;
}

//horizontal collision
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;

if (hsp != 0) image_xscale = sign(hsp)*-1;

ANIMATION END EVENT

//freeze last frame of jumping animation
if (sprite_index == spr_conejo_airbourne_up) image_speed = 0;
//when landing animation finishes, change to idle
if (sprite_index == spr_conejo_airbourne_down) sprite_index = spr_conejo_idle;

WHAT's WRONG When the object is on the floor, the sprite doesn't change to spr_conejo_idle. It constantly loops on spr_conejo_airbourne_down. Sometimes while mid air, sprite changes to spr_idle for a few frames.

GIF of behaviour and sprite strips


Solution

    1. Did you give your object a collision mask? I gave it a simple rectangular mask (based on the "idle") sprite and the landing animation seems to trigger as expected.
    2. There are two halves to this:
      1. You do not rewind image index when changing to airborne_down. I changed
        sprite_index = spr_conejo_airbourne_down;
        
        to
        if (sprite_index != spr_conejo_airbourne_down) {
            image_index = 0;
            sprite_index = spr_conejo_airbourne_down;
        }
        
      2. You're not freezing the last frame of airborne_up, you're freezing whichever frame it was during Animation End, which is usually the first frame (since the animation just ended and restarted). I changed
        if (sprite_index == spr_conejo_airbourne_up) image_speed = 0;
        
        to
        if (sprite_index == spr_conejo_airbourne_up) {
            image_speed = 0;
            image_index = image_number - 1;
        }
        

    With all that done, the rabbits(?) seem to be going about their business pretty normally.

    Test project YYZ

    enter image description here