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.space()
, KeyboardButton.insert()
, KeyboardButton.escape()
and so on. That means if you want to have any sort of key configuration you need a dictionary to map space
to KeyboardButton.space()
, escape
to KeyboardButton.escape()
because you’ll be storing ‘space’ in a configuration file, not KeyboardButton.space()
.
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.