-
Notifications
You must be signed in to change notification settings - Fork 0
Input
Every input source in texastoast has the same two methods, poll() and
is_pressed(), so a game can swap keyboard for hardware without changing.
poll() returns an InputState — eight booleans and two derived axes:
state = keyboard.poll()
state.up, state.down, state.left, state.right
state.a, state.b, state.start, state.select
state.dx # -1.0, 0.0 or 1.0
state.dy # -1.0, 0.0 or 1.0
state.is_any_direction()Opposite directions cancel: holding left and right gives dx == 0.0.
dx/dy are raw axis reads and are not normalized — a diagonal has
magnitude 1.41, not 1. Entity.move normalizes for you. If you integrate
position yourself, do it too:
import math
dx, dy = state.dx, state.dy
mag = math.hypot(dx, dy)
if mag > 1.0:
dx, dy = dx / mag, dy / mag
x += dx * speed * dt
y += dy * speed * dtfrom texastoast import KeyboardInput
keyboard = KeyboardInput(game.root)
game.on_close(keyboard.destroy) # release the bindings on exit| Button | Keys |
|---|---|
| up / down / left / right | Arrow keys, WASD |
| a | Z, Enter |
| b | X, Backspace |
| start | Escape, P |
| select | Shift |
KeyboardInput binds on construction and tracks state until told otherwise. It
is a state source, not an event source: poll() tells you what is held right
now. For one-shot actions — confirming a menu, advancing dialogue — bind a key
event instead, because polling will fire on every frame the key is down:
def on_key(event):
if event.keysym in ("z", "Return"):
dialogue.dismiss()
game.bind_key("<Key>", on_key)destroy() removes every binding and clears the state. It is idempotent.
Prefers hardware when it is actually responding, and falls back to the keyboard otherwise:
from texastoast.input.magma_hub import CompositeInput, MagmaHubInput
controls = CompositeInput(keyboard, MagmaHubInput(hub))
state = controls.poll()
controls.active_source # "magma_hub", "keyboard" or "none"Either argument may be None. With neither, poll() returns an idle state
rather than raising.
The fallback is decided per call by hub.connected, so unplugging the hardware
returns control to the keyboard on the next poll — provided something is
polling the hub, since connected reflects the last poll's outcome.
In 0.1.x a hub on a dead or mock bus reported itself connected, so
CompositeInputlatched onto it and keyboard input stopped working altogether. See Magma Hub and I2C.
Anything with poll() and is_pressed() works — there is no base class to
inherit. InputSource in texastoast.input.abstract is a typing.Protocol
you can use for type checking:
class ReplayInput:
def __init__(self, frames):
self._frames = iter(frames)
self._state = InputState()
def poll(self):
self._state = next(self._frames, self._state)
return self._state
def is_pressed(self, button):
return getattr(self._state, button, False)texastoast · PyPI · Apache-2.0