Python Forum
Thread Rating:
  • 1 Vote(s) - 1 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] Joystick Input
#1
Hi there. I think I'm having trouble with clearing the joystick buffer. Can anyone help?

The project I'm working on allows the user to navigate a menu with the joypad. I found that I was getting a lot (to many / buffered input) of positive reads from my controller using the arrow pad. So I thought I would just look out for some of the Joystick events and read them in all in one go (thus clearing the buffer) but I think I must be applying it incorrectly or going about it all wrong.

Here's what I've got so far.

clsJoystick.py
import pygame
pygame.init()


class InputDevice:
    def __init__(self):
        self._name =None
        self._button =[]
        self._button_total =0
        self._hat =[]
        self._hat_total =0
        self._axis =[]
        self._axis_total =0
    # __init__() ------------------------------------------------------------

# InputDevices --------------------------------------------------------------



class Controller:
    """Version 1.0
    Class - Joystick controller to assist with managing game controllers.
    Properties - axis, buttons, hats.
    Methods - joystick_count, joystick_name.
    """
# ---------------------------------------------------------------------------
# Description:
#   Designed to assist with handling the input from a joystick controller.
#
# Properties:
#   axis
#       Return: <list object>
#           The statuses of axis for this joystick.
#
#   buttons
#       Return: <list object>
#           The statuses of the buttons registered on this
#       controller.
#
#   hats
#       Return: <list object>
#           The statuses of arrow pads registered on this
#       controller.
# ---------------------------------------------------------------------------
    def __init__(self, index):
        self._device =None

        if pygame.joystick.get_count(): #   There's at least one game device connected.
            if index <=(pygame.joystick.get_count() -1): # index in range.
                self._device =InputDevice()
                self._index =index
                pygame.joystick.Joystick(index).init() # Initialise before first use.

                self._device._name =self.joystick_name(index)
                self._device._button_total =pygame.joystick.Joystick(index).get_numbuttons()
                self._device._hat_total =pygame.joystick.Joystick(index).get_numhats()
                self._device._axis_total =pygame.joystick.Joystick(index).get_numaxes()

                #    ------------- Prep list for buttons -------------
                #   Lets create the ellements in our list so we can store the
                # button states in them.
                for bi in range(self._device._button_total):
                    self._device._button.append(None)
                #   _.

                #    ------------- Prep list for hats -------------
                #   Examine the state of the arrow pad (NOT sticks) to see if the
                # player has pressed the pad to go left, right, up, etc.
                for hi in range(self._device._hat_total):
                    self._device._hat.append(None)
                #   _.

                #    ------------- Prep list for axis -------------
                #   Examing the state of the axis and store the
                # data in our list.
                for ai in range(self._device._axis_total):
                    #self.__axis.append(self.__joystick.get_axis(i))
                    self._device._axis.append(None)
                #   _.
            # end if
        # end if
    # __init__() ------------------------------------------------------------
    
    
    @property
    def axis(self):
        'Method - scans the device and returns the status of all the axis.'
        if not self._device ==None:
            return self._device._axis
        # end if
        
    # axis() ----------------------------------------------------------------


    @property
    def buttons(self):
        'Method - scans the device and returns the status of all the buttons.'
        if not self._device ==None:
            return self._device._button
        # end if
        
    # buttons() -------------------------------------------------------------

    
    @property
    def hats(self):
        'Method - scans the device and returns the status of all the hats.'
        if not self._device ==None:
            return self._device._hat
        # end if
        
    # hats() ----------------------------------------------------------------



    @staticmethod
    def joystick_count():
        'Mehtod - returns the number of controllers connected to device.'
        return pygame.joystick.get_count()
    # joystick_count() ------------------------------------------------------

    

    @staticmethod
    def joystick_name(joystick_index):
        'Method - returns the name of the joystick.'
        joystick =pygame.joystick.Joystick(joystick_index)
        
        return joystick.get_name()
    # joystick_name() -------------------------------------------------------


    def read_joystick_buffer(self):
        'Read all the events from pygame.'
        #   Reset the array.
        for hi in range(self._device._hat_total):
            self._device._hat[hi] =(0, 0)
        #   _.
        
        #   Events
        for event in pygame.event.get():
            print("Event type:", event.type)
            if event.type ==pygame.constants.JOYHATMOTION:
                for hi in range(self._device._hat_total):
                    eh1, eh2 =pygame.joystick.Joystick(self._index).get_hat(hi)
                    print("Hat values from pygame:", eh1, eh2)
                    if eh1 !=0 or eh2 !=0:
                        deh1, deh2 =self._device._hat[hi]
                        if eh1 !=0:
                            deh1 =eh1
                        # end if
                        if eh2 !=0:
                            deh2 =eh2
                        # end if
                        self._device._hat[hi] =(deh1, deh2)
                        print(self._device._hat[hi])
                    # end if
                # end for
                
                for bi in range(self._device._button_total):
                    self._device._button[bi] =pygame.joystick.Joystick(self._index).get_button(bi)
                # end for

                for ai in range(self._device._axis_total):
                    self._device._axis[ai] =pygame.joystick.Joystick(self._index).get_axis(ai)
                # end for
            # end if
        # end for loop
                
##            JOYAXISMOTION
##            JOYBALLMOTION
##            JOYBUTTONDOWN
##            JOYBUTTONUP
##            JOYHATMOTION
##
##            # Note: do the events stay there if they are NOT looked at
##            # (keyboard) ??? 
    
# Controller() ------------------------------------------------------
My test file "Joystick_test.py"
import pygame
pygame.init()

from clsJoystick import Controller

#   Open a window so that events can be received.
pygame.display.set_mode((640, 480))
#   _.


print("Total number of controllers:", Controller.joystick_count())
js =[None, None, None, None] # Up to 4 controllers

js[0] =Controller(index =0)


js[0].read_joystick_buffer()

print("Axis:", js[0].axis)
print("Buttons:", js[0].buttons)
print("Hats:", js[0].hats)
I made sure pygame has an open window otherwise it seems there are no events.

Output:
Total number of controllers: 1 Event type: 1 Axis: [None, None, None, None, None, None] Buttons: [None, None, None, None, None, None, None, None, None, None, None] Hats: [(0, 0)]
Reply
#2
Why are you storing them. Pygame allows you to call this data.
Either through events and/or states.
example
import pygame
pygame.init()

def main():
    pygame.display.set_caption('JoyStick Example')
    surface = pygame.display.set_mode((800, 600))
    clock = pygame.time.Clock()
    running = True

    font = pygame.font.Font(None, 20)
    linesize = font.get_linesize()
    joysticks = [pygame.joystick.Joystick(i) for i in range(pygame.joystick.get_count())]
    for joy in joysticks:
        joy.init()

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

        surface.fill((0,0,0))
        position = [10, 10]

        for joy in joysticks:
            image = font.render('name: ' + joy.get_name(), 1, (0,200,0))
            surface.blit(image, position)
            position[1] += linesize

            image = font.render('button count: {0}'.format(joy.get_numbuttons()), 1, (0,200,0))
            surface.blit(image, position)
            position[1] += linesize

            for i in range(joy.get_numbuttons()):
                if joy.get_button(i):
                    image = font.render('{0}: push'.format(i), 1, (0,200,0))
                    surface.blit(image, position)
                    position[1] += linesize

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

    pygame.quit()

main()
99 percent of computer problems exists between chair and keyboard.
Reply
#3
That's a good point, thanks for the tip.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Rasp Pi Analog Joystick mmagner2022 1 2,369 Feb-07-2022, 10:19 PM
Last Post: Larz60+
  [PyGame] Converting PyGame 2 axis joystick float to 360 angle archieab 1 3,337 Sep-26-2018, 05:40 PM
Last Post: archieab
  [PyGame] Using joystick module from PyGame archieab 6 16,207 Sep-25-2018, 06:13 PM
Last Post: archieab
  [PyGame] Limiting a Joystick value -1 to +1, to a value between 0 an 127 with 64 being center? japreja 2 4,461 Dec-10-2017, 06:20 AM
Last Post: japreja

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020