check if button is held down?

Doesn’t panda provide a method to check if button is held down? I could use a task to “accept” a button and change a boolean variable each frame, but the code gets messy. Doesn’t Panda have something like this builtin?

Nothing built in; we figure the code to do it yourself’s not that messy. You don’t need to change your boolean variable every frame, only when the transition event comes in.

That said, there is a ModifierButtons in Panda that is designed to track the state of the shift, alt, and control keys; and you can add any other keys you like to the list of keys it tracks (up to a certain limit). So you could use this class to track your own keys if you really wanted to, but it would be something of a hack.


Umm, there is a way! I started to code with Panda3D just yesterday and ran into the same problem. The code to poll a button state is as follows:

from pandac.PandaModules import KeyboardButton
upArrowIsPressed = base.mouseWatcherNode.isButtonDown(KeyboardButton.up())
wIsPressed = base.mouseWatcherNode.isButtonDown(KeyboardButton.asciiKey("w")

I guess this qualifies as something close to a hack, too, since it makes use of the fact that the mouseWatcherNode doesn’t check whether the passed parameter really is a mouse and not a keyboard button, but it works fine.

Nice. It saves me from storing and modifying the state in every function which is used by accept and the key.

I think the functionality of the class could be copy-pasted into a new class, like KeyWatcherNode, so others would find it more easily: not searching a forum topic for a hack.

There is already a class providing this functionality, and it can be found via the API documentation: InputState. It works for keyboard keys and mouse buttons.

from direct.showbase.InputStateGlobal import inputState

inputState.watchWithModifiers('attack', 'mouse1')
inputState.watchWithModifiers('forward', 'w')

def myTask(task):
  print inputState.isSet('attack')
  print inputState.isSet('forward')
  return task.cont

Nice, and it seems to have been around for few years.
However I’m not sure if it’s bettet than a hack: with MouseWatcher you don’t need “watch” the keys, you just check if a button is held down when you need to, or so it seems.
And the class is poorly documented. I’m not sure, but I guess simple “watch()” is what I’m looking for, but I’m left to guess what arguments it wants.

You can view that class. It’s written in Python and placed in direct/controls/ .

Internally it uses the event system (through DirectObject) that is described in the manual.

I guess, but should you really search the engine’s source for this kind of stuff?

What makes you think this class is not better than a hack? Because you need to configure it before you use it? Look at the code snippet above: you assign input slots to logical commands, then use the logical commands in the code.

Almost every games I have been playing in the last ten years had configurable input. Some gamers want to move their avatars using WASD keys, some like IJKL, some prefer arrow keys. If you want to have such a feature too then you definitely don’t want to poll the user’s configuration everywhere in the code where you handle user input. You sooner or later end up with a class similar to InputState. Consider it a blueprint how you COULD implement it yourself.

No, because it has to “watch()” it, which might be slower than just checking it when needed. Also you probably will need to take care of “unwatching” it when you are done, which seems less convenient.

Are you certain that it is slower? Actually it might be faster. Evaulate how often your key up/down state changes versus how often you need to poll the key up/down state.

Yes, this might be less convenient. Convenience is often in conflict with robust, modular and maintainable design. On the long run often the later one wins. But I don’t want to take influence on your coding style.

I’m quite certain that it is slower as it introduces the overhead of having to use an event system and because polling a key isn’t such an expensive task on the low level. The difference isn’t noticeable, however. Furthermore, I think that "watch()"ing the keys is very convenient, as writing “isSet(‘forward’)” is significantly clearer than writing “isSet(‘ARROW_UP’)” or the like, plus it allows for easy remapping of the keyboard.