Python/Pygame - Jump key does not always register

I have a problem with jumping in pygame. Basically my sprite will sometimes refuse to jump when I tap the jump key quickly. This is a platform game so quick taps for jumping are key to the game mechanics. I don't think that it is an issue with the event queue as the jumping sound still plays even when the sprite does not jump.

complete code:http://pastebin.com/D1B5yuEx

main loop:

        while 1:

            timer.tick(30)

            for e in pygame.event.get():
                    if e.type == KEYDOWN:
                            if e.key == K_ESCAPE:
                                    pygame.quit()
                                    sys.exit()

                    if e.type == KEYDOWN and e.key == K_w:
                            jump.play()
                            up = True
                    if e.type == KEYDOWN and e.key == K_s:
                            down = True
                    if e.type == KEYDOWN and e.key == K_a:
                            left = True
                            last_key_pressed = "LEFT"
                    if e.type == KEYDOWN and e.key == K_d:
                            right = True
                            last_key_pressed = "RIGHT"
                    if e.type == KEYDOWN and e.key == K_e:
                            select = True
                    if e.type == KEYDOWN and e.key == K_SPACE:
                            if inventory.count("PISTOL") == 1:

                                    bullet = Bullet()
                                    shoot_fx.play()
                                    bullet.rect.x = player.rect.x +20
                                    bullet.rect.y = player.rect.y +20
                                    bullets.add(bullet)
                                    if bullet.rect.x == player.rect.x +100:
                                            print "hi"

                                    if right or last_key_pressed =="RIGHT":
                                            bullet.xvel = 7
                                    if left or last_key_pressed =="LEFT":
                                            bullet.xvel = -7    

                    if pygame.joystick.get_count() != 0:
                            if inventory.count("PISTOL") == 1:
                                    if my_joystick.get_button(2) == 1:

                                            bullet = Bullet()
                                            shoot_fx.play()
                                            bullet.rect.x = player.rect.x +20
                                            bullet.rect.y = player.rect.y +20
                                            bullets.add(bullet)

                                            if right or last_key_pressed =="RIGHT":
                                                    bullet.xvel = 7
                                            if left or last_key_pressed =="LEFT":
                                                    bullet.xvel = -7


                    if e.type == KEYUP and e.key == K_w:
                            up = False
                    if e.type == KEYUP and e.key == K_s:
                            down = False
                    if e.type == KEYUP and e.key == K_a:
                            left = False
                    if e.type == KEYUP and e.key == K_d:
                            right = False



            if pygame.joystick.get_count() != 0:

                    if my_joystick.get_axis(0) == -1:
                            last_key_pressed = "LEFT"#left
                            left = True
                    else:
                            left = False

                    if my_joystick.get_axis(0) > .9:
                            last_key_pressed = "RIGHT"
                            right = True
                    else:
                            right = False

                    if my_joystick.get_button(1) == True:

                            up = True
                    else:
                            up = False

                    if my_joystick.get_button(3) == True:
                            select = True
                    else:
                            select = False








            for y in range(20):
                    for x in range(40):
                            screen.blit(bg, (x * 64, y * 64))
            bullets.update(left,right)

            camera.update(player)


            player.update(shoot,up, down, left, right, select,pickups,platforms,inventory,player,bullets)
            for e in entities:
                    screen.blit(e.image,camera.apply(e))
            for b in bullets:
                    screen.blit(b.image,camera.apply(b))

            pygame.display.update()

player class:

class Player(Entity):

    walking_frames_l = []
    walking_frames_r = []

    jumping_r = []
    jumping_l = []

    run_frames_r = []
    run_frames_l = []


    def __init__(self, x, y):
            image = pygame.image.load("C:\Users\Tom\Data\Art\Player1.png")
            self.walking_frames_r.append(image)
            image = pygame.image.load("C:\Users\Tom\Data\Art\Player11.png")
            self.walking_frames_r.append(image)
            image = pygame.image.load("C:\Users\Tom\Data\Art\Player11.png")
            self.walking_frames_r.append(image)
            image = pygame.image.load("C:\Users\Tom\Data\Art\Player2.png")
            self.walking_frames_r.append(image)
            image = pygame.image.load("C:\Users\Tom\Data\Art\Player22.png")
            self.walking_frames_r.append(image)
            image = pygame.image.load("C:\Users\Tom\Data\Art\Player3.png")
            self.walking_frames_r.append(image)
            image = pygame.image.load("C:\Users\Tom\Data\Art\Player33.png")
            self.walking_frames_r.append(image)
            image = pygame.image.load("C:\Users\Tom\Data\Art\Player4.png")
            self.walking_frames_r.append(image)
            image = pygame.image.load("C:\Users\Tom\Data\Art\Player44.png")
            self.walking_frames_r.append(image)

            image = pygame.image.load("C:\Users\Tom\Data\Art\Player1.png")
            image = pygame.transform.flip(image,True,False)
            self.walking_frames_l.append(image)
            image = pygame.image.load("C:\Users\Tom\Data\Art\Player11.png")
            image = pygame.transform.flip(image,True,False)
            self.walking_frames_l.append(image)
            image = pygame.image.load("C:\Users\Tom\Data\Art\Player11.png")
            image = pygame.transform.flip(image,True,False)
            self.walking_frames_l.append(image)
            image = pygame.image.load("C:\Users\Tom\Data\Art\Player2.png")
            image = pygame.transform.flip(image,True,False)
            self.walking_frames_l.append(image)
            image = pygame.image.load("C:\Users\Tom\Data\Art\player22.png")
            image = pygame.transform.flip(image,True,False)
            self.walking_frames_l.append(image)
            image = pygame.image.load("C:\Users\Tom\Data\Art\player3.png")
            image = pygame.transform.flip(image,True,False)
            self.walking_frames_l.append(image)
            image = pygame.image.load("C:\Users\Tom\Data\Art\player33.png")
            image = pygame.transform.flip(image,True,False)
            self.walking_frames_l.append(image)
            image = pygame.image.load("C:\Users\Tom\Data\Art\player4.png")
            image = pygame.transform.flip(image,True,False)
            self.walking_frames_l.append(image)
            image = pygame.image.load("C:\Users\Tom\Data\Art\player44.png")
            image = pygame.transform.flip(image,True,False)
            self.walking_frames_l.append(image)

            self.frame_r = 0
            self.frame_l = 0

            self.last_key_pressed = None

            Entity.__init__(self)
            self.xvel = 0
            self.yvel = 0
            self.onGround = False
            self.image = self.walking_frames_r[self.frame_r]
            self.rect = Rect(x,y,23,31)



    def update(self,shoot,up, down, left, right,select, pickups, platforms, inventory, player,bullets):

            if shoot:
                    pass


            if up:
                    if self.onGround: self.yvel -= 7
            if down:
                    pass
            if left:

                    self.last_key_pressed = "LEFT"
                    self.xvel = -4
                    self.frame_l += 1
                    self.image = self.walking_frames_l[self.frame_l]
                    if self.frame_l == 8: self.frame_l = 0
            if right:

                    self.last_key_pressed = "RIGHT"
                    self.xvel = 4
                    self.frame_r += 1
                    self.image = self.walking_frames_r[self.frame_r]
                    if self.frame_r == 8: self.frame_r = 0

            if not (left or right):
                    if self.last_key_pressed == "LEFT":
                            self.facing = 1
                            self.image = self.walking_frames_l[1]

                    if self.last_key_pressed == "RIGHT":
                            self.facing = 0
                            self.image = self.walking_frames_r[1]


            if not self.onGround:

                    self.yvel += 0.3

                    if self.yvel > 30: self.yvel = 30
            if not(left or right):
                    self.xvel = 0

            self.rect.left += self.xvel

            self.collide(self.xvel, 0,pickups, platforms,select,inventory)

            self.rect.top += self.yvel

            self.onGround = False;

            self.collide(0, self.yvel, pickups, platforms,select,inventory)

    def collide(self, xvel, yvel,pickups, platforms,select,inventory):
            for p in platforms:
                    if sprite.collide_rect(self, p):
                            if isinstance(p, ExitBlock):
                                    pygame.quit
                            if xvel > 0: self.rect.right = p.rect.left
                            if xvel < 0: self.rect.left = p.rect.right
                            if yvel > 0:
                                    self.rect.bottom = p.rect.top
                                    self.onGround = True
                                    self.yvel = 0
                            if yvel < 0: self.rect.top = p.rect.bottom
                            if yvel < 0: self.yvel = 3
            for p in pickups:
                    if sprite.collide_rect(self,p) and select == True:
                            if inventory.count("PISTOL") < 1:
                                    inventory.append(ITEMS.item.items[0])

Answers


In your event handler, you're handling all the events in the queue. If the keydown and keyup events come close enough together, they'll be handled one after the other and the global up variable won't ever get seen as True by the rest of your program. You need to grab that rising edge of the up variable and make sure it doesn't get set back to False before player's update method gets called.

Do you need to set up to False when it's released? If so, you probably want another jump variable that can get set to False when the jump is processed.

I noticed that your joystick jump button handling won't play the sound. You might want to consider using functions to handle button presses instead of directly modifying your global state. It would let you only have that PISTOL handling code once, too.


Need Your Help