Ignore keyboard presses for some time

Hi, all!

I didn’t find anything about how keyboard events can be easily ignored for some period. Let’s say player opened a game, got into main menu, pressed “Start”, and it started to load the game. If someone will press a button at this moment, the game will shutdown, as keyboard events are already designated, but the game is not completely loaded yet - some objects are missing.

Is there a way to disable keyboard? Like, for example, we can disable all sounds and then turn them back with disableAllAudio() and enableAllAudio()?

I think this is easy to implement with the help of an additional flag in the processing function.

1 Like

Well, you can used the “ignore” and “ignoreAll” methods to have whichever object “accepts” your key-presses no longer respond to them. However, this does then mean “accepting” them anew once the designated time is up.

Something like this:

from direct.showbase.ShowBase import ShowBase

class MyGame(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        self.timer = 0
        self.accept("e", self.someMethod)

        self.taskMgr.add(self.update, "update")

    def startPeriodOfIgnoringKeypresses(self):
        self.ignore("e")
        self.timer = 5

    def restoreKeyEvents(self):
        self.accept("e", self.someMethod

    def update(self, task):
        dt = self.clock.getDt()

        if self.timer > 0:
            self.timer -= dt
            if self.timer <= 0:
                self.restoreKeyEvents()

    def someMethod(self):
        print ("Mew! :3")

(Note that with a bit of cunning, one likely need not have one line per key-event in each of the “startPeriodOfIgnoringKeypresses” and “restoreKeyEvents” methods.)

Note, too, that “ignoreAll” will cause the object to ignore, well, all events–keyboard, collision, and so on and so on. It might be preferable to have it only “ignore” the specific keyboard events that you use.

Otherwise, a relatively-simple approach (as suggested by Serega, above) might be to put a bit of “guard-code” into whatever methods your key-events call, which simply returns from those methods if it finds that they’re called during the designated period.

Something like this:

from direct.showbase.ShowBase import ShowBase

class MyGame(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        self.timer = 0
        self.accept("e", self.someMethod)

        self.taskMgr.add(self.update, "update")

    def startPeriodOfIgnoringKeypresses(self):
        self.timer = 5

    def update(self, task):
        dt = self.clock.getDt()

        if self.timer > 0:
            self.timer -= dt

    def someMethod(self):
        if self.timer > 0:
            return

        print ("Mew! :3")

I don’t think time is of the utmost importance here, the author wanted to disable input.

from direct.showbase.ShowBase import ShowBase

class Game(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        self.input_status = False

        self.accept("w", self.forward)

    def forward(self):
        if self.input_status:
            print("forward")
        else:
            print("input disabled")

game = Game()
game.run()

I think that I was going off of the mention of doing this for “some period”–which perhaps suggested to me that it was intended to be done for a given amount of time.

However, the exact nature of the condition isn’t all that important, I feel–the important thing is the approaches that use that condition, whether it be via early-outing or having Panda “ignore” events.

Okay, yeah, I guess, flag is the best option. Thanks.

True, with the help of flags, you will be able to build many behavior trees, for example, disabling the mouse and keyboard separately, there are also gameplay moments, for example, a cut scene where only one button is needed, and so on.

As for time, panda has an indirect implementation of a timer.

from direct.showbase.ShowBase import ShowBase

class Game(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        self.input_status = False

        base.accept("w", self.forward)
        base.taskMgr.do_method_later(5, self.timer, 'timer')

    def timer(self, task):
        self.input_status = True

    def forward(self):
        if self.input_status:
            print("forward")
        else:
            print("input disabled")

game = Game()
game.run()

This turns on the control after five seconds.

1 Like