I was trying to make program to control my mouse with my PS4 controller, everything works fine, I get the data and I can move my mouse accordingly. However when I hold my joystick to any axis, the mouse doesn't move, it not only happens when I hold it, but whenever the joystick value doesn't change. Is there any way I can fix this?
import pygame
import os
import pyautogui
pygame.init()
pygame.joystick.init
j = pygame.joystick.Joystick(0)
j.init()
data = {}
while True:
for event in pygame.event.get():
if event.type == pygame.JOYAXISMOTION:
data[event.axis] = round(event.value, 2)
if event.type == pygame.JOYBUTTONUP:
data["test"] = "letsgoooo"
if event.type == pygame.JOYBUTTONDOWN:
if "test" in data:
del data["test"]
if 0 in data and 1 in data:
if data[0] > 0.08:
pyautogui.move(5, 0, 0.1)
if data[0] < -0.08:
pyautogui.move(-5, 0, 0.1)
if data[1] > 0.08:
pyautogui.move(0, 10, 0.1)
if data[1] < -0.08:
pyautogui.move(0, -10, 0.1)
if 0 in data and 1 in data and 2 in data and 3 in data and 4 in data and 5 in data:
os.system('cls')
print(f"Left:\nX = {data[0]}, Y = {data[1]}")
print(f"Right:\nX = {data[2]}, Y = {data[3]}")
print(f"Left trigger = {data[5]}, Right trigger = {data[4]}")
print(f"Mouse: X = {pyautogui.position()[0]}, Y = {pyautogui.position()[1]}")
print(data)
else:
print("Move your joystick")
The joystick sends update events. I guess a bit like the mouse, if it doesn't emit an event, you must assume the mouse hasn't changed position. Joystick events are the same, if the joystick says it's at
0.753
and there hasn't been an event since, well it's still at that angle.So your movement code needs to remember the most-recent axis value, and use this as the current position of the stick. When a new event comes then you update the value, but not otherwise. That way then the stick is positioned to "full lock" (e.g.: 100% left) you just keep re-positioning whatever the joystick is moving the maximum amount each frame.
The left directional-keypad on the PS4 controller is a PyGame "hat", so not does not generate events, you have to query it independently. For whatever reason up and down seem to generate reverse values to what a normal person would expect (at the time of writing anyway).
I made some example code that moves 3 cross-hairs(sp?) around the window. One for each stick, and one for the hat. It will also show which buttons are pressed. The code could probably do with a re-organisation. I don't like the way the hat has to be handled separately to stick-events, etc. But it's a reasonably good demonstration how it all fits together.
Oh, and the left & right triggers are also single-axis joysticks, but I didn't really do much with them in the code, other than
pass
on the events.