Fluid controls: moving multiple directions at once

I’m working with code to get a character to move in various directions. My current method needs to be cleaned up (above all with lerp intervals) a little, but I doubt that would cause the issue… The issue is that the keyboard commands from one method interrupt the keyboard commands from the other or something. Basically, I have it set up so that you can hold the button to keep moving in a direction, but if I press a different direction, then it executes that command instead, and interrupts the other one. This is an issue, as it leads to very unfluid control.

        
        self.taskMgr.add(self.yax, "yax")
        self.taskMgr.add(self.xax, "xax")        

I added the tasks… for simplicity’s sake, I’m just going to include two, the movement on the X and Y axes.

    def xset(self, tf):
        pcam.xset(self, tf)    
    def yset(self, tf):
        pcam.yset(self, tf)    

(I put all the methods in their own module. in pcam:)

def YC(self, task):
    self.accept('w-repeat',self.yset, ["frepeat"])
    self.accept('w',self.yset,["f"])
    self.accept('s-repeat',self.yset, ["brepeat"])
    self.accept('s',self.yset,["b"])
    self.camera.setPos(0,self.d,0)
    self.camera.lookAt(self.dummynode)
    return Task.cont

def XC(self, task):
    self.accept('a-repeat',self.xset, ["lrepeat"])
    self.accept('a',self.xset,["l"])
    self.accept('d-repeat',self.xset, ["rrepeat"])
    self.accept('d',self.xset,["r"])
    self.camera.setPos(0,self.d,0)
    self.camera.lookAt(self.dummynode)
    return Task.cont    

def yset(self, tf):
    if tf=="brepeat":
        tf="b"
    elif tf=="frepeat":
        tf="f"    
    if tf=="f":
        self.face.setY(self.face, -2)
    else:
        self.face.setY(self.face, 2)

def xset(self, tf):
    if tf=="lrepeat":
        tf="l"
    elif tf=="rrepeat":
        tf="r"    
    if tf=="r":
        self.face.setX(self.face, -2)
    else:
        self.face.setX(self.face, 2)

This code is also simplified for brevity; in the full version it checks for “double tapping” which makes it move faster. But AFAIK, it should allow me to hold both the A button and the W button and go in two directions at the same time. What’s wrong with my code? Is it an inherent limitation of the keyboard checks? Is there a better way to do this that I’m missing? I looked at Roaming Ralph, but I’m purposefully avoiding taking code directly from that, as this is a school project and about half of my project’s total goals are fulfilled in exactly that code (teacher wouldn’t like it)…
Any help would be much appreciated.

Why don’t you use Vectors? With a Vec3 you can move your object in 3 directions!

Just use one Task, and check if A is pressed and W is pressed. Now change your vector and change position. That’s like I would do!

I think the quickest (and easiest) algorithm would be:

Have an array of booleans, one element for each button
Every time you run through your update loop, set each boolean in the array to the value of its corresponding key
If a boolean is True (i.e, its button is pressed), add a small positional change that moves the character in that button/boolean’s direction

That should be easy to implement, and it’s similar to what Roaming Ralph does.

In addition to what DangerOnTheRanger wrote, don’t use “-repeat” messages. Instead, use “key” and it’s corresponding “key-up” messages. You don’t need to handle repeating, all you need to know is when the Player presses the key and when they release it.

Then you can just have a method that will set the values in the boolean array aforementioned to True (reacting to “key”) or False (reacting to “key-up”).

That, and the array, should make your code a lot shorter, cleaner and simpler. Just make sure you don’t over-complicate the array.

As for using vectors, that doesn’t really matter.

Ah, okay. I’ll try that out. Thanks. :slight_smile: