probleme with self.accept and the focus

Hi all, I’m on a little game engine, but I have a problem,

I init the keyboard like that :

        self.accept("arrow_left", self.SetKey, ["xMove", 1, 1])
        self.accept("arrow_right", self.SetKey, ["xMove", -1, 1])
        self.accept("arrow_up", self.SetKey, ["yMove", 1, 1])
        self.accept("arrow_down", self.SetKey, ["yMove", -1, 1])
        self.accept("arrow_left-up", self.SetKey, ["xMove", -1, -1])
        self.accept("arrow_right-up", self.SetKey, ["xMove", 1, -1])
        self.accept("arrow_up-up", self.SetKey, ["yMove", -1, -1])
        self.accept("arrow_down-up", self.SetKey, ["yMove", 1, -1])    

The SetKey is really simple :

def SetKey(key, value, numKey):
self.keyMap["keys"] += numKey
self.keyMap[key] += value

In the keymap[“keys”] I have the number of key pressed (so I can know when the player stop moving, and change his state, and he can push other key without problems)

Then, the script read the xMove and yMove values and return me the direction.

But, when I click outside my Panda Windows, my player go down forever (I had had a push “r” event to reset him :angry:)
I print all of my values, when it bug, I had this :
keys : -4, xMove : 0, yMove : 0
Where the problem, how my script can set -4 to my number of pushed keys ?

(Sorry for my english :smiley:)

add this to your script :


and you’ll see that each time your window lost it’s focus, Panda would throw allKeys-up events. That’s what caused -4.

You want to store the “key pressed” status for several keys. The status can be either “pressed” (True) or “not pressed” (False). Of course 0 and 1 works too. So you want to have a dictionary { key : status }.

This would be one way to solve this:

    def __init__( self ):
        self.keys = { "xMove": False }
        self.accept("arrow_left",    self.SetKey, ["xMove", True])
        self.accept("arrow_left_up", self.SetKey, ["xMove", False])

    def SetKey( self, key, value ):
        self.keys[ key ] = value

    def ...( self ):
        if self.keys[ "xMove" ]: do something...
        else: do something else...

Another way would be to use a bitfield. Less pythonic though, but more enigmatic. Bit number 5 would be “xMove” here in this example:

    def __init__( self ): 
        self._keys = 0
        self.accept("arrow_left",    self.SetKey, [5,0])
        self.accept("arrow_left_up", self.SetKey, [5,1])

    def SetKey( self, index, value ):
        value      = (value&1L)<<index
        mask       = (1L)<<index
        self._keys = (self._keys & ~mask) | value

    def GetKey( self, index ):
        return (self._keys >> index) & 1

    def ...( self ):
        if self.GetKey( 5 ): do something....
        else: do something else...


yea ^^
thanks all, I study it :smiley: