0
# Input Devices
1
2
Game controllers, joysticks, and other input devices.
3
4
## Quick Reference
5
6
```python
7
# Get devices
8
joysticks = pyglet.input.get_joysticks()
9
controllers = pyglet.input.get_controllers()
10
11
# Open and use
12
controller = controllers[0]
13
controller.open()
14
window.push_handlers(controller)
15
16
# Access state
17
if controller.buttons[0]: # Button pressed
18
print("Button 0 pressed")
19
print(controller.leftx, controller.lefty) # Analog stick
20
```
21
22
## Joysticks
23
24
```python
25
def pyglet.input.get_joysticks(display=None) -> list:
26
"""Get all joystick devices"""
27
28
class pyglet.input.Joystick:
29
"""Generic joystick/gamepad"""
30
31
# Properties
32
device: Device
33
name: str
34
35
# Methods
36
def open(window=None)
37
def close()
38
39
# Access after opening
40
@property
41
def buttons() -> list[bool] # Button states
42
@property
43
def axes() -> list[float] # Axis values (-1.0 to 1.0)
44
45
# Events (register with window.push_handlers(joystick))
46
def on_joybutton_press(joystick, button)
47
def on_joybutton_release(joystick, button)
48
def on_joyaxis_motion(joystick, axis, value)
49
def on_joyhat_motion(joystick, hat_x, hat_y)
50
```
51
52
## Game Controllers
53
54
```python
55
def pyglet.input.get_controllers(display=None) -> list:
56
"""Get all game controllers (standardized mapping)"""
57
58
class pyglet.input.Controller:
59
"""Game controller with standard button/axis mapping"""
60
61
# Properties
62
name: str
63
guid: str
64
65
# Methods
66
def open(window=None)
67
def close()
68
69
# Buttons (boolean properties, True when pressed)
70
a, b, x, y: bool
71
leftshoulder, rightshoulder: bool
72
leftstick, rightstick: bool # Stick buttons
73
start, back, guide: bool
74
dpad_up, dpad_down, dpad_left, dpad_right: bool
75
76
# Axes (float properties, -1.0 to 1.0)
77
leftx, lefty: float # Left analog stick
78
rightx, righty: float # Right analog stick
79
lefttrigger, righttrigger: float # Triggers (0.0 to 1.0)
80
81
# Events
82
def on_button_press(controller, button)
83
def on_button_release(controller, button)
84
def on_stick_motion(controller, stick, xvalue, yvalue)
85
def on_dpad_motion(controller, dpleft, dpright, dpup, dpdown)
86
def on_trigger_motion(controller, trigger, value)
87
```
88
89
## Examples
90
91
### Basic Controller Input
92
```python
93
controllers = pyglet.input.get_controllers()
94
if controllers:
95
controller = controllers[0]
96
controller.open()
97
window.push_handlers(controller)
98
99
def update(dt):
100
if controller.a:
101
player.jump()
102
103
# Analog movement
104
player.velocity_x = controller.leftx * player.max_speed
105
player.velocity_y = controller.lefty * player.max_speed
106
107
pyglet.clock.schedule_interval(update, 1/60)
108
```
109
110
### Controller Events
111
```python
112
controller = pyglet.input.get_controllers()[0]
113
controller.open()
114
115
@controller.event
116
def on_button_press(controller, button):
117
print(f"Button pressed: {button}")
118
119
@controller.event
120
def on_stick_motion(controller, stick, xvalue, yvalue):
121
print(f"Stick {stick}: ({xvalue:.2f}, {yvalue:.2f})")
122
123
window.push_handlers(controller)
124
```
125
126
### Deadzone Handling
127
```python
128
def apply_deadzone(value, deadzone=0.2):
129
"""Apply circular deadzone"""
130
if abs(value) < deadzone:
131
return 0.0
132
# Scale remaining range
133
sign = 1 if value > 0 else -1
134
return sign * ((abs(value) - deadzone) / (1.0 - deadzone))
135
136
def update(dt):
137
x = apply_deadzone(controller.leftx)
138
y = apply_deadzone(controller.lefty)
139
player.move(x, y)
140
```
141
142
### Multiple Controllers
143
```python
144
controllers = pyglet.input.get_controllers()
145
players = []
146
147
for i, controller in enumerate(controllers[:4]): # Max 4 players
148
controller.open()
149
window.push_handlers(controller)
150
players.append(Player(controller_id=i))
151
152
def update(dt):
153
for i, player in enumerate(players):
154
controller = controllers[i]
155
player.velocity_x = controller.leftx * player.max_speed
156
if controller.a:
157
player.jump()
158
```
159
160
### Controller Vibration (if supported)
161
```python
162
# Not all controllers/platforms support this
163
try:
164
controller.rumble_play(strength=0.5, duration=0.2)
165
except AttributeError:
166
pass # Vibration not supported
167
```
168
169
## Tablets (Graphics Tablets)
170
171
```python
172
def pyglet.input.get_tablets(display=None) -> list:
173
"""Get graphics tablets"""
174
175
class pyglet.input.Tablet:
176
"""Graphics tablet"""
177
name: str
178
179
def open(window)
180
def close()
181
182
# Events
183
def on_enter(cursor) # Cursor entered window
184
def on_leave(cursor) # Cursor left window
185
def on_motion(cursor, x, y, pressure, tiltx, tilty, buttons)
186
```
187
188
## Apple Remote (macOS)
189
190
```python
191
def pyglet.input.get_apple_remote(display=None):
192
"""Get Apple Remote (macOS only)"""
193
194
class pyglet.input.AppleRemote:
195
"""Apple Remote control"""
196
def open(window, exclusive=False)
197
def close()
198
199
# Events
200
def on_button_press(button)
201
def on_button_release(button)
202
```
203
204
## Common Issues
205
206
1. **Controller not detected**: Check drivers, USB connection
207
2. **Incorrect mapping**: Use Controller class for standardized layout
208
3. **Deadzone**: Raw analog values can drift, apply deadzone
209
4. **Multiple controllers**: Track by index or GUID
210
5. **Platform differences**: Test on target platforms
211
212
## Performance Tips
213
214
1. **Poll vs Events**: Use properties for polling, events for discrete actions
215
2. **Deadzone**: Apply to prevent drift and jitter
216
3. **Close devices**: Always close when done
217
4. **Cache controller list**: Don't call get_controllers() every frame
218