Utilizing different sprites for idling and movement

P

PlazmaNitro

Guest
I am attempting to use 8 different sprites for 4 different directions (WASD). I have idling sprites for each direction, as well as walking animation sprites. This is for a top down 2.5 d view, like Link to the Past on the SNES.

When the game is launched, the sprite assumes the "Down" idling position (facing the screen), which is great.
Pushing W, A, S, or D will initiate movement and the correct walking animation for the respective directions. My issue is that upon releasing all movement keys, the sprite will again assume the "Down" idling position again, regardless of the position it was facing when moving.

How do I get it to use the right position for stopping rightwards motion, left for leftwards, etc.?

Here is the code currently in use (yes playerdirection is defined in the creation event, it says playerdirection = 1 or 2 or 3 or 4;):

//Sprite Control
if (keyboard_check(ord('A'))) { sprite_index = Spr_Left } {image_speed = 0.25;} {playerdirection = 1;}
if (keyboard_check(ord('W'))) { sprite_index = Spr_Up } {image_speed = 0.25;} {playerdirection = 2;}
if (keyboard_check(ord('D'))) { sprite_index = Spr_Right } {image_speed = 0.25;} {playerdirection = 3;}
if (keyboard_check(ord('S'))) { sprite_index = Spr_Down } {image_speed = 0.25;} {playerdirection = 4;}

if !(keyboard_check(ord('A'))) and !(keyboard_check(ord('W'))) and !(keyboard_check(ord('D'))) and !(keyboard_check(ord('S'))) and (playerdirection = 1) {sprite_index = Spr_Resting_Left}
if !(keyboard_check(ord('A'))) and !(keyboard_check(ord('W'))) and !(keyboard_check(ord('D'))) and !(keyboard_check(ord('S'))) and (playerdirection = 2) {sprite_index = Spr_Resting_Up}
if !(keyboard_check(ord('A'))) and !(keyboard_check(ord('W'))) and !(keyboard_check(ord('D'))) and !(keyboard_check(ord('S'))) and (playerdirection = 3) {sprite_index = Spr_Resting_Right}
if !(keyboard_check(ord('A'))) and !(keyboard_check(ord('W'))) and !(keyboard_check(ord('D'))) and !(keyboard_check(ord('S'))) and (playerdirection = 4) {sprite_index = Spr_Resting_Down}
 
F

FadenK

Guest
You're brackets ({ and }) are misused.
I'll post the proper way to do this with an explanation momentarily.
 

obscene

Member
Stop stop stop! :)

Totally forget your question. You need to go back a step. Your existing code is both too complicated to work with and if you continue it's going to take a 8,000 computer to just run your keyboard checks.

Every time you tell GM to check_keyboard, GM has to stop whatever it could be doing to go check the keyboard. You're telling it to check each key 5 times. You have 20 keyboard checks when it should only take as few as ONE, and only as many as 4.

First less, IF statements and ELSE IF statements. If you expect more than one thing to be true, use multiple IF statements. Example...

if the sky is blue
if the grass is green

If you only expect one thing to be true, you do this....

if the sky is blue
else if the sky is green

The advantage being that if the sky is blue, GM does not have to check if the sky is green. That's half the processing power.

Second lesson... ELSE statemetns. (Not ELSE IF). Example...

if left direction=1
else if right direction=2
else if up direction=3
else if down direction=4
else idle=true;

Think on that, rewrite code... you'll find your solution while you do it.
 
F

FadenK

Guest
Add this to create event:
Code:
///Setup
image_speed = 0.25;
playerdirection = 4;


Step Event:
Code:
///Sprite Control
if (keyboard_check(ord('A')))
{
    sprite_index = Spr_Left;
    playerdirection = 1;
}
else if (keyboard_check(ord('W')))
{
    sprite_index = Spr_Up;
    playerdirection = 2;
}
else if (keyboard_check(ord('D')))
{
    sprite_index = Spr_Right;
    playerdirection = 3;
}
else if (keyboard_check(ord('S')))
{
    sprite_index = Spr_Down;
    playerdirection = 4;
}

if !(keyboard_check(ord('A'))) and !(keyboard_check(ord('W'))) and !(keyboard_check(ord('D'))) and !(keyboard_check(ord('S'))) then
{
    switch( playerdirection )
    {
        case 1:
            sprite_index = Spr_Resting_Left;
            break;
        case 2:
            sprite_index = Spr_Resting_Up;
            break;
        case 3:
            sprite_index = Spr_Resting_Right;
            break;
        case 4:
            sprite_index = Spr_Resting_Down;
            break;
    }
}
 

obscene

Member
FadenK's code is an improvment but DO NOT use this line...

if !(keyboard_check(ord('A'))) and !(keyboard_check(ord('W'))) and !(keyboard_check(ord('D'))) and !(keyboard_check(ord('S'))) then

The whole thing can be replaced with this...

Code:
else
If you just asked the game if the sky was blue, it's pointless to ask it if the sky is not blue. You already know the answer.
 
F

FadenK

Guest
This is not the most efficient way to do this, but since the issue isn't efficiency, it should work for what you want.

You can move image_speed = .25 to the create event since it doesn't change.

When you write a statement (such as an if ... then statement) it checks for TRUE logic. Such as IF the statement is true THEN run the following code. GML will only run the next line of code. if the next line of code is an open bracket ( { ) then it tells the compiler to run all the lines of code until an end bracket is reached ( } ). Therefore after the first code block ( code surrounded by brackets ), your code is no longer in IF statement.

Switch statements are like stacked if , else if statements checking a single variable. The values to check for are called cases. A switch/case statement could be used with keyboard_lastkey or keyboard_lastchar. This way you are only reading the keyboard once. There is a "break;" in every case to prevent the code from continuing through the next case.

I would suggest reading in the manual (F1 book) about the different statements and their syntax.

[Edit]
I used the code the way I did so it would be robust, resilient to changes, and understandable to the person with the issue.
 

obscene

Member
I'm just trying to prevent the next topic "why is my game so laggy" and it takes 40 replies to the topic to find there are 782 keyboard checks. :p
 
F

FadenK

Guest
I'm not saying you're wrong.

The way I wrote it for the users is not the way I would do it, however, the user doesn't have 11 years of GML experience. I try to deliver the code and tips/explanations to the user at a level similar to their apparent level of knowledge; that I believe will help them grow. If you give them a tip they can't figure out, or code they can't understand, then you're not really helping them progress as a programmer. At that point, you are just helping them develop their game. I'm not trying to boast or shoot you down, this is just what I believe. I'd rather guide than confuse.
 
Last edited by a moderator:
Top