Unless I’m missing some hidden information not available in the manual and reference - the polling interface (
base.mouseWatcherNode.is_button_down) is bad.
The length of the name is one thing:
if base.mouseWatcherNode.is_button_down.KeyboardButton.ascii_key(u'q'): self.do_jump()
There’s a different API for ‘normal’ keys
KeyboardButton.ascii_key() and a different for ‘special’ keys
KeyboardButton.escape() and so on. That means if you want to have any sort of key configuration you need a dictionary to map
KeyboardButton.escape() because you’ll be storing ‘space’ in a configuration file, not
It gets worse if you add mouse and controllers to the mix - there is no one way to watch for a key press that is common for all input devices. If you want to jump with the space you’ll watch for
KeyboardButton.space(), if you want to jump with the mouse it will be
MouseButton.three(), if you want to jump with a gamepad button… yeah, you got something like
if self.gamepad.find_button("lstick").pressed: (after setting up self.gamepad first, and that’s another extra bit of code…).
Why is this all so needlessly complicated?
Using events you have
self.accept(key_name, self.do_jump) and
key_name can be a keyboard button (
n) a special keyboard button (
space) a mouse button (
mouse3) it could be a controller key after some extra setup.
Coudn’t we just have a InputDeviceWatcher with a dictionary-like interface so that we could just do:
if base.InputDeviceWatcher['keyboard-space']: self.do_jump() if base.InputDeviceWatcher['mouse-1']: self.fire_zer_missile('!')
and it should also work for analogue axis:
x_axis = base.InputDeviceWatcher['gamepad-x-axis'] #returns a value in -1.0, 1.0 range self.ship.set_h(self.ship.get_h()+x_axis*dt*rotation_speed)
Sorry if this looks like a rant (it kind of is), but reacting to player action is what makes games games and it should be as simple as loading a model and parenting it to render, you shouldn’t need 200+ lines of obscure code just for watching if a key/button is pressed.