1

I am trying to use a ps4 controller with a raspberry pi to generate inputs. I have sucessfully connected the controller and when i try and run the following code found on the pygame website everything is working fine.

import pygame


BLACK    = (   0,   0,   0)
WHITE    = ( 255, 255, 255)


class TextPrint:
    def __init__(self):
        self.reset()
        self.font = pygame.font.Font(None, 20)

    def print(self, screen, textString):
        textBitmap = self.font.render(textString, True, BLACK)
        screen.blit(textBitmap, [self.x, self.y])
        self.y += self.line_height

    def reset(self):
        self.x = 10
        self.y = 10
        self.line_height = 15

    def indent(self):
        self.x += 10

    def unindent(self):
        self.x -= 10


pygame.init() 
size = [500, 700]
screen = pygame.display.set_mode(size)
pygame.display.set_caption("My Game")


done = False

clock = pygame.time.Clock()


pygame.joystick.init()


textPrint = TextPrint()


while done==False:

    for event in pygame.event.get(): # User did something
        if event.type == pygame.QUIT: # If user clicked close
            done=True # Flag that we are done so we exit this loop

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



    screen.fill(WHITE)
    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.3f}".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()

        textPrint.unindent()



    pygame.display.flip()


    clock.tick(20)

pygame.quit ()

So yeah when i run the above code everything works fine, however i didn't want to generate a game at all, and i'm only interested in getting the inputs from the d pad or the hats. in order to do this i wrote my own code based off the code above

 import pygame
    pygame.joystick.init()
    while True:
        joystick = pygame.joystick.Joystick(0)
        joystick.init()
        hat = joystick.get_hat(0)
        print(str(hat))

When i run the above code it runs and there are no syntax errors, however it continuously prints(0,0) regardless of what buttons of the d-pad i have pressed. The controller is still connected, which suggests to me that for some reason my new code isn't recieving inputs.

Thank you for taking the time to read this long post, any help would be much appreciated.

Kind regards

1 Answers1

0

You have to call one of the pygame.event functions regularly (for example pygame.event.pump or for event in pygame.event.get():), otherwise functions like Joystick.get_hat and pygame.mouse.get_pressed won't work and the pygame window will become unresponsive after a while.

You also don't need to create and initialize a new joystick object each frame. Do that once before the while loop. Here's a minimal, complete example:

import pygame as pg


pg.init()
screen = pg.display.set_mode((100, 100))
clock = pg.time.Clock()

# Create a list of available joysticks and initialize them.
joysticks = [pg.joystick.Joystick(x) for x in range(pg.joystick.get_count())]
for joystick in joysticks:
    joystick.init()

running = True
while running:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            running = False
        elif event.type == pg.JOYBUTTONDOWN:
            if event.button == 6:  # Back button.
                running = False

    for joystick in joysticks:  # Iterate over the available joysticks.
        if joystick.get_id() == 0:  # The first joystick.
            numhats = joystick.get_numhats()
            for hat in range(numhats):  # Check all hats of the joystick.
                print(joystick.get_hat(hat))

    screen.fill((30, 30, 50))
    pg.display.flip()
    clock.tick(60)

pg.quit()
skrx
  • 19,980
  • 5
  • 34
  • 48