Code for 8 direction "WASD"

A

Aaron McDonald

Guest
Hi,
so I'm attempting to program the animations for 8 direction movement using "WASD." I can't figure out the syntax though for talking about pressing only one key, or pressing both keys. Here's the pseudocode for what I'm trying:

IF ('S' key is pressed BUT NOT 'A' key or 'D' key)
THEN {play "forward" animation...}

IF ('S' key and 'A' key are both pressed)
THEN {play "forwardLeft" animation}

etc...

The main thing that's confusing to me is how to use the "keyboard_check_pressed(ord('S'))" syntax in combination with the '!' assignment and other keys presses. Hope my question makes sense, thank you!
 

Nux

GameMaker Staff
GameMaker Dev.
bitwise is a pretty fun and compact way to do this!
Code:
var W = keyboard_check(ord("W"));
var A = keyboard_check(ord("A"))*2; // shift by 1 bit
var S = keyboard_check(ord("S"))*4; // shift by 2 bits
var D = keyboard_check(ord("D"))*8; // shift by 3 bits

var a = W|A|S|D;
if ONLY "W" is pressed, then argument will be 1 (or 0001)
if BOTH "W" AND "S" are pressed but NOT "A" and "D" the value will be 5 (or 0101 - this is because I have shifted S across 2 bits)

in relality, your pseudo code would look like this:
Code:
var W = keyboard_check(ord("W"));
var A = keyboard_check(ord("A"))*2; // shift by 1 bit
var S = keyboard_check(ord("S"))*4; // shift by 2 bits
var D = keyboard_check(ord("D"))*8; // shift by 3 bits

var a = W|A|S|D;

if (a == 4) // since S = 0100 = 4
{
    sprite_index = spr_forward;
}
else if (a == 6) // since S (4) + A (2) = 6
{
    sprite_index = spr_forward_left;
}
[...]
EDIT: changed "argument" to "a"
 
Last edited:

HayManMarc

Member
Simple answer for newbie:


IF ('S' key is pressed BUT NOT 'A' key or 'D' key)
THEN {play "forward" animation...}

if keyboard_check(ord('S')) && !keyboard_check(ord('D'))
{play animation}

-------------

IF ('S' key and 'A' key are both pressed)
THEN {play "forwardLeft" animation}

if keyboard_check(ord('S')) && keyboard_check(ord('A'))
{play animation}
 
A

Aaron McDonald

Guest
Hi Nux,
your way looks pretty good. I'm just struggling to get it to work. Here's my code:
Code:
///scr_playerMovement

if keyboard_check(ord('A'))
   {
        x += -spd;
   }
  
if keyboard_check(ord('D'))
   {
        x += spd;
   }
  
if keyboard_check(ord('W'))
   {
        y += -spd;
   }
  
if keyboard_check(ord('S'))
   {
        y += spd;
   }
  
var W = keyboard_check(ord("W"));
var A = keyboard_check(ord("A"))*2; // shift by 1 bit
var S = keyboard_check(ord("S"))*4; // shift by 2 bits
var D = keyboard_check(ord("D"))*8; // shift by 3 bits

var argument = W|A|S|D;

if (argument == 4) // since S = 0100 = 4
{
    sprite_index = spr_playerFrontForward;
}

else
{
    sprite_index = spr_playerFrontIdle;
}
I'm sure there's something that would be stupidly obvious to most people. But it gives me an error message on the line right before "var argument = W|A|S|D;" saying that you can't redeclare a variable that's built-in. And the reason everything else goes to "spr_playerFrontIdle" is because I'm just trying to figure out how to get the forward motion working for the time being. Thanks for your response!
 

Nux

GameMaker Staff
GameMaker Dev.
Oh i'm terribly sorry! rename argument to something other than a built in variable. E.g: a or val.

I probably should have used a unique name, im sorry.
it doesn't matter what you call "argument":

Code:
var W = keyboard_check(ord("W"));
var A = keyboard_check(ord("A"))*2; // shift by 1 bit
var S = keyboard_check(ord("S"))*4; // shift by 2 bits
var D = keyboard_check(ord("D"))*8; // shift by 3 bits

var a = W|A|S|D;

if (a == 4) // since S = 0100 = 4
{
   sprite_index = spr_playerFrontForward;
}

else
{
    sprite_index = spr_playerFrontIdle;
}
changing argument to any variable name of you choice should fix it
 
Last edited:
A

Aaron McDonald

Guest
Holy hell, it works!
Thank you! Your kindness, Nux, will not be forgotten...
 
  • Like
Reactions: Nux
A

Aaron McDonald

Guest
Sorry to open this back up, Nux, but I'm wondering how to deal with a little glitch: The problem is when the player hits combo-keys: like "D" & "S" or the "A" & "S" keys together. the player object isn't using the animation I specified. Any idea what I'm doing wrong?

Thanks!

Code:
var W = keyboard_check(ord("W"))*1;
var A = keyboard_check(ord("A"))*4; // shift by 1 bit
var S = keyboard_check(ord("S"))*6; // shift by 2 bits
var D = keyboard_check(ord("D"))*8; // shift by 3 bits

var movementNum = W|A|S|D;

//"S" Down
if (movementNum == 6)
{
   sprite_index = spr_playerFrontForward;
}

//"S/D" down/right
else if (movementNum == 15)
{
    sprite_index = spr_playerRight;
}

//"D" Right
else if (movementNum == 8)
{
    sprite_index = spr_playerRight;
}

//"D/W" Right/Up
else if (movementNum == 9)
{
    sprite_index = spr_playerRight;
}

//"W" Up
else if (movementNum == 1)
{
    sprite_index = spr_playerBackwards;
}

//"W/A" Up/Left
else if (movementNum == 5)
{
    sprite_index = spr_playerLeft;
}

//"A" Left
else if (movementNum == 4)
{
    sprite_index = spr_playerLeft;
}

//"A/S" Left/Down
else if (movementNum == 10)
{
    sprite_index = spr_playerLeft;
}

//No keys No movement
else
{
    sprite_index = spr_playerFrontIdle;
}
 

Nux

GameMaker Staff
GameMaker Dev.
Sorry to open this back up, Nux, but I'm wondering how to deal with a little glitch: The problem is when the player hits combo-keys: like "D" & "S" or the "A" & "S" keys together. the player object isn't using the animation I specified. Any idea what I'm doing wrong?

Thanks!

Code:
var W = keyboard_check(ord("W"))*1;
var A = keyboard_check(ord("A"))*4; // shift by 1 bit
var S = keyboard_check(ord("S"))*6; // shift by 2 bits
var D = keyboard_check(ord("D"))*8; // shift by 3 bits

var movementNum = W|A|S|D;

//"S" Down
if (movementNum == 6)
{
   sprite_index = spr_playerFrontForward;
}

//"S/D" down/right
else if (movementNum == 15)
{
    sprite_index = spr_playerRight;
}

//"D" Right
else if (movementNum == 8)
{
    sprite_index = spr_playerRight;
}

//"D/W" Right/Up
else if (movementNum == 9)
{
    sprite_index = spr_playerRight;
}

//"W" Up
else if (movementNum == 1)
{
    sprite_index = spr_playerBackwards;
}

//"W/A" Up/Left
else if (movementNum == 5)
{
    sprite_index = spr_playerLeft;
}

//"A" Left
else if (movementNum == 4)
{
    sprite_index = spr_playerLeft;
}

//"A/S" Left/Down
else if (movementNum == 10)
{
    sprite_index = spr_playerLeft;
}

//No keys No movement
else
{
    sprite_index = spr_playerFrontIdle;
}
typing error ;o;
You have it set to 15 instead of 14 (6+8 =14 not 15)

EDIT:
So actually, 15 would be S and A and W (because of the extra 1)
just change 15 to 14
 
A

Aaron McDonald

Guest
Lol, yeah I saw and fixed that earlier. But the problem still exists with the "A" and "S" combination. When both keys are pressed, in any order, it resorts to the playerFrontForward animation instead of the playerLeft animation.
 

Nux

GameMaker Staff
GameMaker Dev.
Oh okay, i see the problem, it must be because you've typed the first bit wrong.

Code:
var W = keyboard_check(ord("W"))*1;
var A = keyboard_check(ord("A"))*4; // shift by 1 bit
var S = keyboard_check(ord("S"))*6; // shift by 2 bits
var D = keyboard_check(ord("D"))*8; // shift by 3 bits
to shift a bit it needs to be a power of 2:
1, 2, 4, 8

since you've used: 1, 4, 6, 8...
when you shift them S will look like:
Code:
0110
and A and S will look like:
Code:
0110 or 0010

this results to 0110
look familiar?

Basically what i'm saying is change
Code:
var W = keyboard_check(ord("W"))*1;
var A = keyboard_check(ord("A"))*4; // shift by 1 bit
var S = keyboard_check(ord("S"))*6; // shift by 2 bits
var D = keyboard_check(ord("D"))*8; // shift by 3 bits
to
Code:
var W = keyboard_check(ord("W"))*1;
var A = keyboard_check(ord("A"))*2; // shift by 1 bit
var S = keyboard_check(ord("S"))*4; // shift by 2 bits
var D = keyboard_check(ord("D"))*8; // shift by 3 bits

You will have to redo your arguments though.
S == 4
S/D == 12 (because 4 + 8 = 12)
S/A == 6 (because 4+2 = 6)
etc...
 
A

Aaron McDonald

Guest
Wow, well I guess I had a fundamental misunderstanding of what it meant to shift a bit. I'll have to actually learn about it! I really appreciate your help, Nux.
 

Nux

GameMaker Staff
GameMaker Dev.
Awh it's okay!
Google it some time, it's an easy concept to grasp, as it's similar to multiplying a number by 10 (2 x 10 = 20, the two is shifted left by one (10 only works with base ten, not binary though))
 
Top