CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyglet

Cross-platform windowing and multimedia library for Python with OpenGL graphics, event handling, and audio/video playback

Overview
Eval results
Files

input-devices.mddocs/

Input Devices

Game controllers, joysticks, and other input devices.

Quick Reference

# Get devices
joysticks = pyglet.input.get_joysticks()
controllers = pyglet.input.get_controllers()

# Open and use
controller = controllers[0]
controller.open()
window.push_handlers(controller)

# Access state
if controller.buttons[0]:  # Button pressed
    print("Button 0 pressed")
print(controller.leftx, controller.lefty)  # Analog stick

Joysticks

def pyglet.input.get_joysticks(display=None) -> list:
    """Get all joystick devices"""

class pyglet.input.Joystick:
    """Generic joystick/gamepad"""

    # Properties
    device: Device
    name: str

    # Methods
    def open(window=None)
    def close()

    # Access after opening
    @property
    def buttons() -> list[bool]  # Button states
    @property
    def axes() -> list[float]  # Axis values (-1.0 to 1.0)

    # Events (register with window.push_handlers(joystick))
    def on_joybutton_press(joystick, button)
    def on_joybutton_release(joystick, button)
    def on_joyaxis_motion(joystick, axis, value)
    def on_joyhat_motion(joystick, hat_x, hat_y)

Game Controllers

def pyglet.input.get_controllers(display=None) -> list:
    """Get all game controllers (standardized mapping)"""

class pyglet.input.Controller:
    """Game controller with standard button/axis mapping"""

    # Properties
    name: str
    guid: str

    # Methods
    def open(window=None)
    def close()

    # Buttons (boolean properties, True when pressed)
    a, b, x, y: bool
    leftshoulder, rightshoulder: bool
    leftstick, rightstick: bool  # Stick buttons
    start, back, guide: bool
    dpad_up, dpad_down, dpad_left, dpad_right: bool

    # Axes (float properties, -1.0 to 1.0)
    leftx, lefty: float  # Left analog stick
    rightx, righty: float  # Right analog stick
    lefttrigger, righttrigger: float  # Triggers (0.0 to 1.0)

    # Events
    def on_button_press(controller, button)
    def on_button_release(controller, button)
    def on_stick_motion(controller, stick, xvalue, yvalue)
    def on_dpad_motion(controller, dpleft, dpright, dpup, dpdown)
    def on_trigger_motion(controller, trigger, value)

Examples

Basic Controller Input

controllers = pyglet.input.get_controllers()
if controllers:
    controller = controllers[0]
    controller.open()
    window.push_handlers(controller)

def update(dt):
    if controller.a:
        player.jump()

    # Analog movement
    player.velocity_x = controller.leftx * player.max_speed
    player.velocity_y = controller.lefty * player.max_speed

pyglet.clock.schedule_interval(update, 1/60)

Controller Events

controller = pyglet.input.get_controllers()[0]
controller.open()

@controller.event
def on_button_press(controller, button):
    print(f"Button pressed: {button}")

@controller.event
def on_stick_motion(controller, stick, xvalue, yvalue):
    print(f"Stick {stick}: ({xvalue:.2f}, {yvalue:.2f})")

window.push_handlers(controller)

Deadzone Handling

def apply_deadzone(value, deadzone=0.2):
    """Apply circular deadzone"""
    if abs(value) < deadzone:
        return 0.0
    # Scale remaining range
    sign = 1 if value > 0 else -1
    return sign * ((abs(value) - deadzone) / (1.0 - deadzone))

def update(dt):
    x = apply_deadzone(controller.leftx)
    y = apply_deadzone(controller.lefty)
    player.move(x, y)

Multiple Controllers

controllers = pyglet.input.get_controllers()
players = []

for i, controller in enumerate(controllers[:4]):  # Max 4 players
    controller.open()
    window.push_handlers(controller)
    players.append(Player(controller_id=i))

def update(dt):
    for i, player in enumerate(players):
        controller = controllers[i]
        player.velocity_x = controller.leftx * player.max_speed
        if controller.a:
            player.jump()

Controller Vibration (if supported)

# Not all controllers/platforms support this
try:
    controller.rumble_play(strength=0.5, duration=0.2)
except AttributeError:
    pass  # Vibration not supported

Tablets (Graphics Tablets)

def pyglet.input.get_tablets(display=None) -> list:
    """Get graphics tablets"""

class pyglet.input.Tablet:
    """Graphics tablet"""
    name: str

    def open(window)
    def close()

    # Events
    def on_enter(cursor)  # Cursor entered window
    def on_leave(cursor)  # Cursor left window
    def on_motion(cursor, x, y, pressure, tiltx, tilty, buttons)

Apple Remote (macOS)

def pyglet.input.get_apple_remote(display=None):
    """Get Apple Remote (macOS only)"""

class pyglet.input.AppleRemote:
    """Apple Remote control"""
    def open(window, exclusive=False)
    def close()

    # Events
    def on_button_press(button)
    def on_button_release(button)

Common Issues

  1. Controller not detected: Check drivers, USB connection
  2. Incorrect mapping: Use Controller class for standardized layout
  3. Deadzone: Raw analog values can drift, apply deadzone
  4. Multiple controllers: Track by index or GUID
  5. Platform differences: Test on target platforms

Performance Tips

  1. Poll vs Events: Use properties for polling, events for discrete actions
  2. Deadzone: Apply to prevent drift and jitter
  3. Close devices: Always close when done
  4. Cache controller list: Don't call get_controllers() every frame

Install with Tessl CLI

npx tessl i tessl/pypi-pyglet

docs

3d-models.md

app-clock.md

audio-video.md

graphics-rendering.md

gui.md

images-textures.md

index.md

input-devices.md

math.md

opengl.md

resource-management.md

sprites-shapes.md

text-rendering.md

windowing.md

tile.json