• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GML Asymmetrical Sprite Facings

K

Krinkles

Guest
I've got a sprite set up that's asymmetrical; the character is in a space suit that has different badges on their left and right arms, and a name tag that's on the left side of their chest.

So far, I've figured out some code that makes the sprite facing change according to the character's movement, but I'm stuck on what to do about his facing while he's not moving, or while he's jumping in place. As it is, when he's doing either, he just plays the walk animation for his last facing in either situation. I need a way to make him idle left/right or use the appropriate left/right facing sprites while jumping strait up.

For all intents and purposes I had no prior coding experience before last week.

This is my current animation code. He moves around fine both with and without it, so I don't think his movement/collision codes are relevant.

///Animation
if (sign(hsp)!=0)
{
if (sign(vsp)==0)
{
if (sign(hsp)>0)
{
if (key_sprint)sprite_index = Run_Right1;
else sprite_index = Walk_Right1;
if (sign(hsp)==0) sprite_index = Idle_Right1
}
if (sign(hsp)<0)
{
if (key_sprint)sprite_index = Run_Left1;
else sprite_index = Walk_Left1;
if (sign(hsp)==0) sprite_index = Idle_Left1
}
}
else
{
if (sign(hsp)>0) sprite_index = Jumping_Right1;
if (sign(hsp)<0) sprite_index = Jumping_Left1;
}

}
 
K

Krinkles

Guest
By sticking

else
{
if (keyboard_check_released(vk_right)) sprite_index = Idle_Right1;
if (keyboard_check_released(vk_left)) sprite_index = Idle_Left1;
}

-on to the end of it, I've gotten the idle facing to work when he's just standing still. However, I still haven't from-idle jump facings. You start moving in a direction he'll turn to face the correct way with the correct sprite, but if you don't press a direction and just hit jump, he just uses his idle sprites and moves up and down.
 

samspade

Member
By sticking

else
{
if (keyboard_check_released(vk_right)) sprite_index = Idle_Right1;
if (keyboard_check_released(vk_left)) sprite_index = Idle_Left1;
}

-on to the end of it, I've gotten the idle facing to work when he's just standing still. However, I still haven't from-idle jump facings. You start moving in a direction he'll turn to face the correct way with the correct sprite, but if you don't press a direction and just hit jump, he just uses his idle sprites and moves up and down.
There are probably a lot of ways to handle this. I would consider a state machine. For example, put all of your actions into states (jump, walk, idle, etc.) and then within those states define which sprites to use.

However, you could probably fix your current issue by checking for vsp or whether there is a floor object beneath the player and if vsp is negative or no floor object them use the jump sprite.
 

TheouAegis

Member
Make a variable. Call it facing. Set it to 0. Make a series of arrays for each state (idle, running, jumping, whatever). For each array, set the right sprite for index 0 and left sprite for index 1. Or vice-versa, depending on how your sprites face by default. When you need to change sprites, just use the array for that sprite and set the index to facing.

sprite_index = Idle_Sprite[facing];

When your hspeed is greater than 0, set facing to 0 (or 1 if your sprites face left by default).
When your hspeed is less than 0, set facing to 1 (or 0 if your... you get the idea).

But yes, I'd consider rewriting your code in a more simplistic state machine. You have a lot of sign() calls. If anything, save the sign() of your hsp and vsp to temporary variables first. Calculating the sign of a variable is a relatively intensive process.
 
K

Krinkles

Guest
There are probably a lot of ways to handle this. I would consider a state machine. For example, put all of your actions into states (jump, walk, idle, etc.) and then within those states define which sprites to use.

However, you could probably fix your current issue by checking for vsp or whether there is a floor object beneath the player and if vsp is negative or no floor object them use the jump sprite.
Make a variable. Call it facing. Set it to 0. Make a series of arrays for each state (idle, running, jumping, whatever). For each array, set the right sprite for index 0 and left sprite for index 1. Or vice-versa, depending on how your sprites face by default. When you need to change sprites, just use the array for that sprite and set the index to facing.

sprite_index = Idle_Sprite[facing];

When your hspeed is greater than 0, set facing to 0 (or 1 if your sprites face left by default).
When your hspeed is less than 0, set facing to 1 (or 0 if your... you get the idea).

But yes, I'd consider rewriting your code in a more simplistic state machine. You have a lot of sign() calls. If anything, save the sign() of your hsp and vsp to temporary variables first. Calculating the sign of a variable is a relatively intensive process.
Well, I don't know anything about arrays or state machines, but I can do some research.
 

TheouAegis

Member
Do you know what a variable is? Do you know to look something up in the back of a textbook? Then you know all you need to know about arrays. :p
 

samspade

Member
Well, I don't know anything about arrays or state machines, but I can do some research.
They're worth researching. There are lots of good Youtube videos on state machines. But I will try to give a brief explanation here.

First, the concept. The concept of a state machine is relatively straight forward. An object has a variety of states (running, jumping, walking, idle, etc.) and each state has a different set of rules (e.g. code) that controls how it acts in that state. The primary benefit of this method is that it allows for easy and complete control of each state. In other words, you can set up the running code to be entirely different from the jumping code and never have any issues.

Next the code. There are a couple ways to do state machines but I prefer the switch statement. The switch statement is essentially a re-ordered if statement. It basically says, find this variable, figure out what this variable is, and then do whatever you're supposed to. (It can get a lot more complicated than that, but that's the basics.)

So a basic state machine for player movement would be:

Code:
switch (state) {

     case "IDLE":
     //idle code
     if (jump) {state = "JUMP";}
     if ((left) || (right)) && (place_meeting(x, y + 1, obj_floor) {state = "WALK"}
     if (shift) && ((left) || (right)) && (place_meeting(x, y + 1, obj_floor) {state = "RUN"}
     break;

     case "WALK":
     //walk code
     //code to switch states
     break;

     case "RUN":
     //run code
     //code to switch states
     break;

     case "JUMP":
     //jump code
     //code to switch states
     break;

}
So tutorials to look up would be tutorials for state (or finite state) machines and switch statements. This stuff is important/usefull enough that I would actually watch several tutorials from several different people to get an idea of how different people think about and use it.
 

TheouAegis

Member
And don't even bother restricting yourself to "game maker" tutorials/blogs/whatever. A finite state machine is a concept, not a code. ...Probably want to stay away from Wikipedia, though. It gets too in-depth.


Want to see a finite state machine in action? Go turn on a light in your home.
 
Top