limit keyboard inpute

is there an easy way to limit the input to only one arrow key at a time?

I want to limit the motion of the player to only up, down, left, and right (using the arrow keys). I don’t want the player to be able to move diagonally. I tried writing code to solve this, but after a few hours of failure, I’m getting frustrated.

[SOLVED]----------------------------------------------------------------------------------------

I used boolean object variables to tell what key was being pressed at any given time. then, in the “if” statements of each movement module, I checked if the other keys were being pressed.

here is a snippet of my solution


def move_right(cont):
        
    right = cont.sensors["right"]
    move = cont.actuators["move"]
    
    x = own.position.x
    a = (round(x, 2))*10 % 1
    b = int((round(a,2))*10)
    #print ("b=",b)
    #print ("a=",a)

   <b> if right.positive and not own["up"] and not own["down"]:          &lt;--the important part</b>
        
        move.dLoc = [0.01, 0.0, 0.0]
        cont.activate(move)
        own["right"] = True
        
    elif b != 0 and b != 5:
        
        right_offset(cont, x, b)
        own["right"] = False
            
    else:
        
        cont.deactivate(move)
        own["right"] = False

Here you are, open the blend file and take a look at the logic :slight_smile:
http://www.pasteall.org/blend/25159

…A easy way is use a property:

A key is activated? the property: “movement” is True.
Is deactivate? the property: “movement” is False

And the character only can move when the property: “movement” is False.

Sorry english.

In code that is pretty easy depending on how you want the game to handle it when user presses another arrow while other is already pressed. But simple if-elif statement (that is mostly filled with actuator and sensor code)


cont = bge.logic.getCurrentController()
s = cont.sensors

#assuming you use actuators to move
moveup = cont.actuators["moveup"]
moveleft = cont.actuators["moveleft"]
moveright = cont.actuators["moveright"]
movedown = cont.actuators["movedown"]

#deactivate all
for ac in cont.actuators:
    cont.deactivate(ac)

if s["up"].positive:
    cont.activate(moveup) #if you move with python dump it here
elif s["down"].positive:
    cont.activate(movedown)
elif s["left"].positive:
    cont.activate(moveleft)
elif s["right"].positive:
    cont.activate(moveright)

This is pretty low-brow because I don’t know your setup and what exactly you want. It just moves the first it finds of up, down, left, right. If you want something more sophisticated tell us more :slight_smile:

I gave your solution a try, but it didn’t work for my setup. I decided to start again from scratch(mostly), and came at the problem from another angle. I was able to get it to work in a similar way as what you described.

here is a snippet of my solution


def move_right(cont):
        
    right = cont.sensors["right"]
    move = cont.actuators["move"]
    
    x = own.position.x
    a = (round(x, 2))*10 % 1
    b = int((round(a,2))*10)
    #print ("b=",b)
    #print ("a=",a)

   <b> if right.positive and not own["up"] and not own["down"]:          &lt;--the important part</b>
        
        move.dLoc = [0.01, 0.0, 0.0]
        cont.activate(move)
        own["right"] = True
        
    elif b != 0 and b != 5:
        
        right_offset(cont, x, b)
        own["right"] = False
            
    else:
        
        cont.deactivate(move)
        own["right"] = False