2

I've seen other solutions to this problem say that you either need to call the pygame.event.pump() or initialize the joystick outside of the while loop. However, even with these solutions, I'm getting 0's for the joystick axes values.

If I uncomment just the pygame.display.set_mode((1, 1)), then the code works as expected, and the values are output to the console.

Is there a way to still get the axes values without having to create the extra window?

Also, I am running python 3.6 on Windows 10.

import pygame

FRAMES_PER_SECOND = 20

pygame.init()
pygame.joystick.init()

# pygame.display.set_mode((1,1))

# Used to manage how fast the screen updates.
clock = pygame.time.Clock()

xboxController = pygame.joystick.Joystick(0)
xboxController.init()


# Loop until the user presses menu button
done = False

print('Found controller\nStarting loop...')
while not done:
    pygame.event.pump()
    for event in pygame.event.get():
        if event.type == pygame.JOYBUTTONDOWN and event.button == 7:
            print(f'Exiting controller loop')
            done = True

    for i in range(xboxController.get_numaxes()):
        print(f'Axis {i}: {xboxController.get_axis(i)}')

    # pygame.display.flip()

    clock.tick(FRAMES_PER_SECOND)

Output:

pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
Found controller
Starting loop...
Axis 0: 0.0
Axis 1: 0.0
Axis 2: 0.0
Axis 3: 0.0
Axis 4: 0.0
.
.
.
Matthew P
  • 113
  • 1
  • 8
  • 1
    Why would you use Pygame without the window? It's a framework for game development, it feels like a hacky way at best to go down that route, especially after searching and looking around how other people hacked around the problem with Pygame and all the problems it rises. Perhaps [this](https://gist.github.com/rdb/8864666) or [this](https://pypi.org/project/inputs/) is a better approach? – Torxed May 25 '20 at 13:43
  • @Torxed Thanks! I'll check out the second link, it seems to do what I want as well. – Matthew P May 25 '20 at 13:48
  • @Torxed Wow the inputs library is way simpler than I thought. Found a better solution in less time – Matthew P May 25 '20 at 13:59
  • Glad it worked, keep in mind for future posts that you should allow us who give you the help to post answers, as otherwise you'll get the points both for asking the questions as well as writing the answers, which kind of defeats the purpose of this website :) – Torxed May 25 '20 at 14:01
  • @Torxed Oops my bad, just made your solution the accepted one. Thanks again :) – Matthew P May 25 '20 at 14:14
  • You're more than welcome, and don't sweat it :) Also, leave your answer as some other people using the pygame approach might have the same issue. Best of luck to you on your projekt :) – Torxed May 25 '20 at 14:21

3 Answers3

6

I would probably move away from Pygame unless you need the whole underlaying GL features, as the library is meant for 2D/3D game development. Although it might be possible to use it for these purposes, issues down the line is more or less unavoidable. A perhaps simpler approach would be to go with python's input library, which can handle gamepads (joysticks).

from inputs import get_gamepad

while True:
    events = get_gamepad()
    for event in events:
        if event.ev_type == 'Absolute':
            if event.code == 'ABS_X':
                print(f'Left joystick x: {event.state}')
            elif event.code == 'ABS_Y':
                print(f'Left joystick y: {event.state}')
            elif event.code == 'ABS_RX':
                print(f'Right joystick x: {event.state}')
            elif event.code == 'ABS_RY':
                print(f'Right joystick y: {event.state}')
Torxed
  • 22,866
  • 14
  • 82
  • 131
2

Alright found the answer 5 minutes after I posted this. The problem was that I was using pygame 1.9.6 instead of 2.0.0.dev8. After updating, I'm getting the console output without the display window.

Torxed
  • 22,866
  • 14
  • 82
  • 131
Matthew P
  • 113
  • 1
  • 8
0

As a further suggested possibility, if you want a window open but don't want to need to interact with it, you can add the following and it should help do what you want, plus an extra command or two:

import os

#This will allow your code to run even when there is a screensaver
os.environ["SDL_VIDEO_ALLOW_SCREENSAVER"] = "1"

# Allow the joystick to work in the background
os.environ["SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS"] = "1"

# If we are willing to take a small performance hit we can maximize
# compatibility with some versions of linux.  
# may be excluded in many cases
os.environ["SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR"] = "0"