Created
August 31, 2025 18:41
-
-
Save rayfarer/10b9434a4ae890050690ed07e453ea9a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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