pythonpygamecontroller

PyGame inputs not working with Nintendo Switch Pro Controller


I'm trying to add controller inputs to a game I'm making but when pressing one of the buttons on the controller, the action is not being performed.

I was told to use JOYHATMOTION but the Pro Controller has 0 hats, so I believe that can't work. I tried using JOYBUTTONUP and JOYBUTTONDOWN yet it still doesn't work

import pygame
from pygame import JOYBUTTONDOWN

import constants as c
class EventHandler:
    def __init__(self):
        pygame.joystick.init()
        self.num_joysticks = pygame.joystick.get_count()
        print(self.num_joysticks)
        self.joystick = None
        if self.num_joysticks:
            self.joystick = pygame.joystick.Joystick(0)
            self.joystick.init()

    def handle_events(self, actor):
        for event in pygame.event.get():
            self.check_quit_event(event)
            self.check_keyboard_event(event, actor)
            self.check_joystick_event(event, actor)

    @staticmethod
    def check_quit_event(event):
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
    def check_keyboard_event(self, event, actor):
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                actor.velocity_x = actor.speed
            elif event.key == pygame.K_LEFT:
                actor.velocity_x = -actor.speed
            if event.key == pygame.K_SPACE:
                actor.shoot()
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT:
                actor.velocity_x = 0
            elif event.key == pygame.K_LEFT:
                actor.velocity_x = 0
    def check_joystick_event(self, event, actor):
        if event.type == JOYBUTTONDOWN:
            if event.type == c.NS_LEFT:
                actor.vel_x = -actor.speed
#Display info
DISPLAY_WIDTH = 350
DISPLAY_HEIGHT = 625
DISPLAY_SIZE = (DISPLAY_WIDTH, DISPLAY_HEIGHT)

#Joystick info
NS_UP = 11
NS_DOWN = 12
NS_LEFT = 13
NS_RIGHT = 14
NS_A = 0
NS_B = 1
NS_START = 6
NS_HOME = 5


Solution

  • The code is testing event.type is both JOYBUTTONDOWN and c.NS_LEFT - it can't be both. (Use event.button )

        def check_joystick_event(self, event, actor):
            if event.type == JOYBUTTONDOWN:
                if event.type == c.NS_LEFT:       # <-- HERE event.type again!
                    actor.vel_x = -actor.speed
    

    Maybe try:

        def check_joystick_event(self, event, actor):
            if event.type == JOYBUTTONDOWN:
                print( "Button [%d] pressed" % ( int( event.button ) ) )
                if event.button == c.NS_LEFT:
                    actor.vel_x = -actor.speed
    

    Side issue: Are you sure of the event codes? Print out event.button in the handler to check.

    Here's a related answer about PS4 controllers I made: https://stackoverflow.com/a/63163852/1730895 You can read it to see how the buttons & hats are handled. Note that joysticks report as absolute position, rather than relative changes. You only get an event when the joystick re-positions. No event indicates the position remains unchanged.