• 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!

[Code] Unbiased 4-Direction Movement

B

Bayesian

Guest
If you're making a top-down retro game you might want to have 4-direction movement with no diagonals. Ideally when you press two keys it should use the latest one and also return when you release and go back to one key. This does just that.

I see it come up sometimes but haven't seen a method for it and I think I found a pretty straight forward way to do it.
I'm calling this "unbiased" because when people post their attempts it always has some unwanted bias. I also don't really know what to call this, let me know if there's a real name for this.

I thought I'd also include my scrGetInput script since its useful.
Code:
///Get input
kUpHeld = keyboard_check(ord("W"))
kUpPressed = keyboard_check_pressed(ord("W"))
kUpReleased= keyboard_check_released(ord("W"))

kLeftHeld = keyboard_check(ord("A"))
kLeftPressed = keyboard_check_pressed(ord("A"))
kLeftReleased = keyboard_check_released(ord("A"))

kDownHeld = keyboard_check(ord("S"))
kDownPressed = keyboard_check_pressed(ord("S"))
kDownReleased = keyboard_check_released(ord("S"))

kRightHeld = keyboard_check(ord("D"))
kRightPressed = keyboard_check_pressed(ord("D"))
kRightReleased = keyboard_check_released(ord("D"))

kSpaceHeld = keyboard_check(vk_space)
kSpacePressed = keyboard_check_pressed(vk_space)
kSpaceReleased = keyboard_check_released(vk_space)

Code:
enum kl{
    kUp,
    kLeft,
    kDown,
    kRight,
}
kLast = -1

Code:
scrGetInput()

//Set kLast based on keydown
if(kUpPressed){
    kLast = kl.kUp
}
if(kLeftPressed){
    kLast = kl.kLeft
}
if(kDownPressed){
    kLast = kl.kDown
}
if(kRightPressed){
    kLast = kl.kRight
}

//Create an axis for keys
var my = kDownHeld - kUpHeld
var mx = kRightHeld - kLeftHeld
/*    Reset kLast after more than one key
    was held but now only one is held but
    the was no key down event to set it above.
*/
//If either no or both vertical keys are held.
if(my==0){
    //If only left is held
    if(mx==-1){
        kLast = kl.kLeft
    //If only right is held
    }else if(mx==1){
        kLast = kl.kRight
    }
}

//If either no or both horizontal keys are held.
if(mx==0){
    //If only up is held
    if(my==-1){
        kLast = kl.kUp
    //If only down is held
    }else if(my==1){
        kLast = kl.kDown
    }
}

//If kLast matches the key that is held.
if(kLast==kl.kUp&&kUpHeld){
    y -= 6   
}
if(kLast==kl.kDown&&kDownHeld){
    y += 6
}
if(kLast==kl.kLeft&&kLeftHeld){
    x -= 6
}
if(kLast==kl.kRight&&kRightHeld){
    x += 6
}
 
D

Danei

Guest
I struggled with how to do this and ended up using a kind of cumbersome priority queue system, which seems to work pretty well but later when I have time I might try yours out in its place because I don't like using PQs unless I have to. Thanks!
 
Top