Legacy GM Animation in Platformer [SOLVED]

I

</iKON1K>

Guest
Hello! I am currently working on animation for my character in my platformer game, and it does not work quite right. Here is the code I currently have
Code:
// Control the sprite
image_speed = sign(len)*.4;
if(len == 0) image_index = 8;
// Vertical sprites
if(vspd > 0){
    sprite_index = s_player_down;
}else if(vspd < 0){
    sprite_index = s_player_up;
}else if(vspd == 0){
    sprite_index = s_player_right;
}
// Horizontal sprite
if(hspd > 0){
    sprite_index = s_player_right;
} else if(hspd < 0){
    sprite_index = s_player_left;
}
Problem is, once my player starts falling, and sprite changes to falling sprite, once the player hits the ground, falling sprite never goes away. I tried to check for ground, and then change the sprite, but it did not work as well. I would love to receive any suggestions on how I should fix that issue. Thank you.
 
N

nicoltoons

Guest
Hi. The thing is vspd can never be less than 0 so in that condition give vspd a higher value than 0 and try again. Even when the player is on the ground , it still retains some vspd.
 
N

nicoltoons

Guest
What I mean is this
if(vspd > 0){
sprite_index = s_player_down;

change that to a value like 2 or 3 but it depends on the height of your player sprite. Fiddle around with the values but it shouldn't be equal to zero. And please ensure that all sprites are within the same bounding box . Helps to jump and fall more accurately. Cheers
 

Hyomoto

Member
To get ahead in your issue, the problem you have is two blocks of code setting sprite index based on different criteria. So, essentially, your sprite will always be the last criteria that is true.

Even if you take @nicoltoons's advice, which should work to fix this issue, you'll hit this same issue when you add another animation. What you really need to is to order your logic based on what your character is doing. This is where you'll hear people suggest a finite state machine, or FSM. Maybe that sounds impressive but it's just a way of ordering our logic.

To simplify the issue, we know the player can not be falling AND walking, so if we were to seperate those from one another we could more easily determine what the player can be doing. Let's say we break them up based on what animation you are currently using:
Code:
if sprite_index == sprite_falling {
  If vsp == 0 { sprite_index == sprite_stand }

} else if sprite_index == sprite_stand {
  If hsp > 0 { sprite_index = sprite_right }

} else if sprite_index == sprite_right {
  If hsp == 0 { sprite_index = sprite_stand }
  If vsp > 0 { sprite_index = sprite_falling }

}
// etc
This is just an example, but hopefully you can see what it's doing. We're breaking up our animation logic based on what sprite is currently being seen, we can then know what sprites it can go to based on that criteria. Using the method you currently have, you'll often have conflicting animations because the criteria is too arbitrary. The player could be moving left while jumping, falling and walking: without knowing what the player is doing it doesn't match every situation, and trying to order it that way will lead to some very complex code. A state machine is just a way for us to simplify that by restricting what checks are made based on what "state" the object is in. And part of that is identifying what criteria is best to make that decision, in this case we can only be in one animation at a time so it's a useful "state" to use.
 
Last edited:
L

Linkdeous

Guest
as nicoltoons said, a speed can't be negative, vspeed is the speed, changiung y + or y - is something else, so you want to change this if statemeent from vspd<0 to if position_meeting(x,y-spriteheight,obj_Wall)
 
N

nicoltoons

Guest
@Hyomoto nice idea to break down her code
but this
if sprite_index == sprite_falling {
If vsp == 0 { sprite_index == sprite_stand }
might still pose an issue because vsp will probably always be greater than zero .Happened with my last game.
 

Hyomoto

Member
@nicoltoons - There is a solution to that, for purposes of topic. Gravity usually is pulling the player down, to simplify:
Code:
vsp = min( vsp + gravity, maxGravity )
When the player collides with the floor you set vsp to 0. So, if you placed this state block after determining collisions, you would get the desired result because vsp would be 0.

To be clear, I'm not advocating this particular solution, but in this case that would be a reasonable solution to that problem. You'd have the same issue with hsp when colliding with a wall as well, so this would work for most situations.
 
I

</iKON1K>

Guest
To get ahead in your issue, the problem you have is two blocks of code setting sprite index based on different criteria. So, essentially, your sprite will always be the last criteria that is true.

Even if you take @nicoltoons's advice, which should work to fix this issue, you'll hit this same issue when you add another animation. What you really need to is to order your logic based on what your character is doing. This is where you'll hear people suggest a finite state machine, or FSM. Maybe that sounds impressive but it's just a way of ordering our logic.

To simplify the issue, we know the player can not be falling AND walking, so if we were to seperate those from one another we could more easily determine what the player can be doing. Let's say we break them up based on what animation you are currently using:
Code:
if sprite_index == sprite_falling {
  If vsp == 0 { sprite_index == sprite_stand }

} else if sprite_index == sprite_stand {
  If hsp > 0 { sprite_index = sprite_right }

} else if sprite_index == sprite_right {
  If hsp == 0 { sprite_index = sprite_stand }
  If vsp > 0 { sprite_index = sprite_falling }

}
// etc
This is just an example, but hopefully you can see what it's doing. We're breaking up our animation logic based on what sprite is currently being seen, we can then know what sprites it can go to based on that criteria. Using the method you currently have, you'll often have conflicting animations because the criteria is too arbitrary. The player could be moving left while jumping, falling and walking: without knowing what the player is doing it doesn't match every situation, and trying to order it that way will lead to some very complex code. A state machine is just a way for us to simplify that by restricting what checks are made based on what "state" the object is in. And part of that is identifying what criteria is best to make that decision, in this case we can only be in one animation at a time so it's a useful "state" to use.
Thank you very much. I changed my animation code, to make it look kind of like your example, and it worked. Thank you very much.
 
Top