pythonpygamejoystickgamepad

Using joystick module from PyGame


Exact code with commenting can be found here, or here.

while done==False:
for event in pygame.event.get():
    if event.type == pygame.QUIT:
        done=True

    if event.type == pygame.JOYBUTTONDOWN:
        print("Joystick button pressed.")
    if event.type == pygame.JOYBUTTONUP:
        print("Joystick button released.")

screen.fill(darkgrey)
textPrint.reset()

joystick_count = pygame.joystick.get_count()

textPrint.print(screen, "Number of joysticks: {}".format(joystick_count) )
textPrint.indent()

for i in range(joystick_count):
    joystick = pygame.joystick.Joystick(i)
    joystick.init()

    textPrint.print(screen, "Joystick {}".format(i) )
    textPrint.indent()

    name = joystick.get_name()
    textPrint.print(screen, "Joystick name: {}".format(name) )

    axes = joystick.get_numaxes()
    textPrint.print(screen, "Number of axes: {}".format(axes) )
    textPrint.indent()

    for i in range( axes ):
        axis = joystick.get_axis( i )
        textPrint.print(screen, "Axis {} value: {:>6.0f}".format(i, axis) )
    textPrint.unindent()

    buttons = joystick.get_numbuttons()
    textPrint.print(screen, "Number of buttons: {}".format(buttons) )
    textPrint.indent()

    for i in range( buttons ):
        button = joystick.get_button( i )
        textPrint.print(screen, "Button {:>2} value: {}".format(i,button) )
    textPrint.unindent()

    hats = joystick.get_numhats()
    textPrint.print(screen, "Number of hats: {}".format(hats) )
    textPrint.indent()

    for i in range( hats ):
        hat = joystick.get_hat( i )
        textPrint.print(screen, "Hat {} value: {}".format(i, str(hat)) )
    textPrint.unindent()

pygame.display.flip()
clock.tick(20)

With the help of the online PyGame documentation, I was able to produce a screen displaying values for individual Joysticks. How would I translate these values to an event that says this button is pressed, now do this?

Something similar to this,

for i in range( axes ):
    axis = joystick.get_axis( i )
    textPrint.print(screen, "Axis {} value: {:>6.0f}".format(i, axis) )

    if Joystick 2's Axis 3 is equal to 1:
        print("Joystick 2 is pointing to the right.")

    if Joystick 2's Axis 3 is equal to -1:
        print("Joystick 2 is pointing to the left.")

textPrint.unindent()

Solution

  • Most games process gamepad inputs as part of the "main loop" which gets run at least once per frame. If you have code to read gamepad inputs then you should put that in the main loop (probably near the top), then have another step afterward that processes the input and updates the game state. That's where you should do things like look at the button values and decide how to translate them into game actions. After the game state is updated you can redraw the display to match the new game state and wait for the next frame.

    You can also treat gamepad inputs as events and handle them synchronously, but it's hard to get this right because the input could come at any time. For most applications it's better to handle all gamepad input at once. If you handle input changes synchronously you may treat updates as independent when they should be taken together. For instance, when a joystick moves the X and Y changes should be treated as part of the same input change. If you aren't careful, treating them independently can produce a stair-stepping pattern when translated to movement within the game.