Search code examples
pythonpygamepacman

Require holding key down for movement in pacman pygame with game pad


I've been modifying the PACMAN pygame code from here. Currently, I have a function that requires players to hold down a direction key in order to keep moving in that direction. The code for that is:

def process_events(self):
        for event in pygame.event.get(): # User did something
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE: # exit program entirely
                    self.run_over = True
                    return True
                elif event.key == pygame.key_r:
                    self.player.move_right()

                elif event.key == pygame.key_l:
                    self.player.move_left()

                elif event.key == pygame.key_u:
                    self.player.move_up()

                elif event.key == pygame.key_d:
                    self.player.move_down()

            elif event.type == pygame.KEYUP:
                if event.key == pygame.key_r:
                    self.player.stop_move_right()
                elif event.key == pygame.key_l:
                    self.player.stop_move_left()
                elif event.key == pygame.key_u:
                    self.player.stop_move_up()
                elif event.key == pygame.key_d:
                    self.player.stop_move_down()

        return False

While this works perfectly for keyboard button presses, I'm trying to incorporate a gamepad, which uses capital letters to designate a key down button press and lower case letters for keyup button presses. For example, when moving in the downward direction, keypress down is "D" and keypress up/release is "d". Using the same function from above with the gamepad results in me having to button mash to barely move. I, therefore, modified the function to this:

def process_events(self):
        for event in pygame.event.get(): # User did something
            try:
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE: # exit program entirely
                        self.run_over = True
                        return True
                    elif event.key == pygame.key_r:
                        self.player.move_right()
    
                    elif event.key == pygame.key_l:
                        self.player.move_left()

    
                    elif event.key == pygame.key_u:
                        self.player.move_up()
    
                    elif event.key == pygame.key_d:
                        self.player.move_down()
            except:   
                self.player.stop_move_right()
                self.player.stop_move_left()
                self.player.stop_move_up()
                self.player.stop_move_down()                

        return False

However, with this new code, I simply tap a direction button and I move in that direction indefinitely until I press a different button. Is there a way for me to modify my code so that the player needs to hold down the gamepad direction button to move and they stop once the button is released?


Solution

  • Thanks to @qouify, I realized that my modified function was incorrectly set up. I therefore adjusted it to this, which now performs the correct functionality:

    def process_events(self):
            counter = []
            for event in pygame.event.get(): # User did something
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE: # exit program entirely
                        self.run_over = True
                        return True
                    else: # direction movement
                        if event.key in [pygame.K_LSHIFT, pygame.K_r, pygame.K_l, pygame.K_u, pygame.K_d]:
                            counter.append(pygame.key.name(event.key))
                        # right
                        if len(counter) == 2 and counter[0] == "left shift" and counter[1] == "r":
                            self.player.move_right()
                        elif len(counter) == 1 and counter[0] == "r":
                            self.player.stop_move_right()
                        # left
                        if len(counter) == 2 and counter[0] == "left shift" and counter[1] == "l":
                            self.player.move_left()
                        elif len(counter) == 1 and counter[0] == "l":
                            self.player.stop_move_left()
                        # up
                        if len(counter) == 2 and counter[0] == "left shift" and counter[1] == "u":
                            self.player.move_up()
                        elif len(counter) == 1 and counter[0] == "u":
                            self.player.stop_move_up()
                        # down
                        if len(counter) == 2 and counter[0] == "left shift" and counter[1] == "d":
                            self.player.move_down()
                        elif len(counter) == 1 and counter[0] == "d":
                            self.player.stop_move_down()
            return False
    

    I realize this may not be the most elegant or "pythonic" solution, in which case I'm happy for anyone to offer suggestions. Otherwise, I'll consider this solved.