Skip to content

Instantly share code, notes, and snippets.

@rayfarer
Created August 31, 2025 18:41
Show Gist options
  • Select an option

  • Save rayfarer/10b9434a4ae890050690ed07e453ea9a to your computer and use it in GitHub Desktop.

Select an option

Save rayfarer/10b9434a4ae890050690ed07e453ea9a to your computer and use it in GitHub Desktop.
import sys
import time
import pygame
from pynput.keyboard import Controller as KeyboardController, Key
# Joystick config
JOYSTICK_INDEX = 0
DPAD_HAT_INDEX = 0
# Axes
STEERING_AXIS = 0
ACCELERATOR_AXIS = 1
# Thresholds
STEERING_DEADZONE = 0.05
STEERING_THRESHOLD = 0.2
ACCELERATOR_THRESHOLD = 0.8 # press space when value <= 0.8
# Buttons
BUTTON_E = 15
BUTTON_Q1 = 4
BUTTON_Q2 = 5
def main():
pygame.init()
pygame.joystick.init()
if pygame.joystick.get_count() == 0:
print("No joystick detected.")
sys.exit(1)
js = pygame.joystick.Joystick(JOYSTICK_INDEX)
js.init()
kb = KeyboardController()
pressed = {
'w': False, 'a': False, 's': False, 'd': False,
'q': False, 'e': False, Key.space: False
}
def press(key):
if not pressed[key]:
kb.press(key)
pressed[key] = True
def release(key):
if pressed[key]:
kb.release(key)
pressed[key] = False
try:
while True:
pygame.event.pump()
# --- HAT → WASD ---
if js.get_numhats() > DPAD_HAT_INDEX:
hx, hy = js.get_hat(DPAD_HAT_INDEX)
if hy == 1:
press('w')
else:
release('w')
if hy == -1:
press('s')
else:
release('s')
if hx == -1:
press('a')
else:
release('a')
if hx == 1:
press('d')
else:
release('d')
# --- Steering Axis → A/D ---
try:
steer_val = js.get_axis(STEERING_AXIS)
if steer_val < -STEERING_THRESHOLD:
press('a')
elif abs(steer_val) <= STEERING_DEADZONE:
release('a')
if steer_val > STEERING_THRESHOLD:
press('d')
elif abs(steer_val) <= STEERING_DEADZONE:
release('d')
except Exception:
release('a')
release('d')
# --- Accelerator → Space ---
try:
accel_val = js.get_axis(ACCELERATOR_AXIS)
if accel_val <= ACCELERATOR_THRESHOLD:
press(Key.space)
else:
release(Key.space)
except Exception:
release(Key.space)
# --- Buttons ---
# Button 15 -> E
if js.get_button(BUTTON_E):
press('e')
else:
release('e')
# Buttons 4 and 5 -> Q
if js.get_button(BUTTON_Q1) or js.get_button(BUTTON_Q2):
press('q')
else:
release('q')
time.sleep(0.01)
except KeyboardInterrupt:
pass
finally:
for k, is_down in pressed.items():
if is_down:
kb.release(k)
if pygame.joystick.get_init():
pygame.joystick.quit()
if pygame.get_init():
pygame.quit()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment