• Hey! Guest! The 36th GMC Jam will take place between February 27th, 12:00 UTC - March 2nd, 12:00 UTC. Why not join in! Click here to find out more!

[Solved] Jumping and falling animation - Stop on last frame and reset

I'm trying to make a jump and falling animation, with animated sprites. I want both of them to stop on the last frame (image_speed = 0), and continue from the first frame, when the jump-button is pressed again.

Code:
//animation
STEP EVENT 

if(!grounded=1) {
    image_speed = 1;
    if (sign(vsp) > 0) {
        image_speed = 1;
        sprite_index = sPlayerF;
    }
    else sprite_index =sPlayerA;
    
    if sprite_index = sPlayerA {
        image_speed = 1;
        if image_index > image_number - 1 {image_speed = 0};
    };
    
    if sprite_index = sPlayerF {
        image_speed = 1;
        if image_index > image_number - 1 {image_speed = 0};
    };
}
else {
  image_speed=1;
  if (hsp==0) {
    sprite_index = sPlayer;
  }
  else {
    sprite_index = sPlayerR;
  }
}
It works fine during the jump animation. It stops on the last frame, and continues from the first once the jump button is pressed again. However, the falling animation is stuck on the last frame from the get go. I don't understand why, as the approach works for the jumping animation. Any help would be appreciated.

(I'm awate that there's some excess use of "image_speed = 1")
 

TheSly

Member
When you change sprites, the frame that the sprite is up to, the image_index, does not get reset. Try resetting that to 0 every time you change sprites.
 
When you change sprites, the frame that the sprite is up to, the image_index, does not get reset. Try resetting that to 0 every time you change sprites.
I guess the fundamental problem is that I don't know how to reset the image_index probably. If i define the image_index the sprite is stuck on that particular index for the whole animation. The code posted above, is an attempt to get around this problem - ie reset the sprite to image by setting image_speed to zero on the last index, and then starting the animation again, the next time the jump button is pressed.

What is the conventional way of resetting an animation in GM Studio 2?
 

TheSly

Member
I guess the fundamental problem is that I don't know how to reset the image_index
When you change sprites, you can set the image_index the first step you change the sprite. The first step you change sprites the sprite will not be equal to the sprite you are changing it to, so you can do it knowing that.
As as example:
Code:
if (hsp==0) {
  if sprite_index != sPlayer image_index = 0;
  sprite_index = sPlayer;
}
 
Thanks for the reply TheSly.

I've got it working somewhat with this:

Code:
Step event

//check player direction
if(hsp !=0) image_xscale=sign(hsp);

//animation
if(!grounded=1) {
    image_speed = 1;
    if (sign(vsp) > 0) {
        image_speed = 1;
        sprite_index = sPlayerF;
    }
    else sprite_index =sPlayerA;
    
    if sprite_index = sPlayerA {
        image_speed = 1;
        if image_index >= image_number - (sprite_get_speed(sprite_index)/room_speed) {image_speed = 0};
    };
    
    if sprite_index = sPlayerF {
        image_speed = 1;
        if image_index >= image_number - (sprite_get_speed(sprite_index)/room_speed) {image_speed = 0};
    };
}
else {
  image_speed=1;
  if (hsp==0) {
    if sprite_index != sPlayer image_index = 0;
    sprite_index = sPlayer;
  }
  else {
    sprite_index = sPlayerR;
  }
}
The problem is, that the jump animation sometimes won't reset. I've tried using the code you suggested, but it dosen't seem to make any difference.
 
Thanks for the reply TheSly.

I've got it working somewhat with this:

Code:
Step event

//check player direction
if(hsp !=0) image_xscale=sign(hsp);

//animation
if(!grounded=1) {
    image_speed = 1;
    if (sign(vsp) > 0) {
        image_speed = 1;
        sprite_index = sPlayerF;
    }
    else sprite_index =sPlayerA;
   
    if sprite_index = sPlayerA {
        image_speed = 1;
        if image_index >= image_number - (sprite_get_speed(sprite_index)/room_speed) {image_speed = 0};
    };
   
    if sprite_index = sPlayerF {
        image_speed = 1;
        if image_index >= image_number - (sprite_get_speed(sprite_index)/room_speed) {image_speed = 0};
    };
}
else {
  image_speed=1;
  if (hsp==0) {
    if sprite_index != sPlayer image_index = 0;
    sprite_index = sPlayer;
  }
  else {
    sprite_index = sPlayerR;
  }
}
The problem is, that the jump animation sometimes won't reset. I've tried using the code you suggested, but it dosen't seem to make any difference.
EDIT: After some testing it seems that the animation will get stuck if jump button is pressed too soon. It seems that there isn't enough time to identify the state of the object.
 

TheSly

Member
Every time you change to a new sprite you need to set the image_index to 0, unless that sprite only has 1 frame.
 
So would this be the correct way to do it?

Code:
Step event

//animation
if(!grounded=1) {
    image_speed = 1;
    if (sign(vsp) > 0) {
        image_speed = 1;
        if sprite_index != sPlayerF image_index = 0;
        sprite_index = sPlayerF;
    }
    else sprite_index = sPlayerA;
    
    if sprite_index = sPlayerA {
        image_speed = 1;
        if image_index >= image_number - (sprite_get_speed(sprite_index)/room_speed) {image_speed = 0};
    };
    
    if sprite_index = sPlayerF {
        image_speed = 1;
        if image_index >= image_number - (sprite_get_speed(sprite_index)/room_speed) {image_speed = 0};
    };
}
else {
  image_speed=1;
  if (hsp==0) {
    if sprite_index != sPlayer image_index = 0;
    sprite_index = sPlayer;
  }
  else {
    sprite_index = sPlayerR;
  }
}
Because I can't get that to work.

My intuition says that it has something to do with real numbers and integers. As far as I understand sprite-index is never an integer? I guess I base that on that it works most of the time, but sometimes it dosen't. I can kind of force the bug, if I jump immediatly after landing.
 
since you cant figure it out Ill try to offer a bandaid, although learning it will help you grow more and this is more duct tape where one needs a screw driver and a screw.
Code:
if grounded
{
count=0
}
else
{
count<13//change this to however many frames in your jumping animation
count++
image_index=count
}
if your game has a double jump obviously you can reset count when you hit the jump button and the check that you can rejump is successfull
what your stating about integers is called floating points, and essentially this is true in most computing the easiest way to check for floating points being a cause of a problem is say your checking for 12 instead of variable=12 use variable>11.01 or >11.5 or similar, image_index loops back at its max so you will never find a point its above its max value.
 
Thanks for the input, I think it makes sense to me. The idea is if the player is grounded the image_index = 0, but if the players is not grounded(i.e. jumping) the image_index should be incrementet every frame by 1?

I'm not sure I think you code is missing something before "count < 13"?

EDIT:

Im guessing you meant:
Code:
if grounded {
    count = 0;
}
else {
    if count < 7 {
        count++;
        image_index = count;
    }
}
This makes the animation really janky, but it does seem to eliminate the problem of it being stuck on the last frame.
 
Last edited:
To anyone having similar problems, I'll post the solution I found to be working:

Code:
if(!grounded) {
    if (sign(vsp) = 1) {
        if sprite_index != sPlayerF {image_index = 0;}
        sprite_index = sPlayerF;
        if image_index >= image_number - (sprite_get_speed(sprite_index)/room_speed) {image_speed = 0};
    }
    if (sign(vsp) = -1) {
        if sprite_index != sPlayerA {image_index = 0;}
        sprite_index = sPlayerA;
        if image_index >= image_number - 1 {image_speed = 0};
    }   
}
else {
  image_speed=1;
  if (hsp==0) {
    if sprite_index != sPlayer {image_index = 0;}
    sprite_index = sPlayer;
  }
  else {
    if sprite_index != sPlayerR {image_index = 0;}
    sprite_index = sPlayerR;
  }
}
 
Top