Search code examples
pythonpygamecollision-detection

Pygame not detecting all key events on collision


I'm new to Python and Pygame and am designing a simple clone of Dance Dance Revolution played with the keyboard. I have it set up to detect the collision between the falling arrow and the static arrow beneath it, and I have it set to detect the proper key presses during collisions. The problem is that it will only detect some of the key presses some of the time. I'm not sure why, and the code has gotten ahead of me.

def collisionDetect(arrow, contact_arrow):
   return pygame.sprite.collide_rect(arrow, contact_arrow)

def game(list):

running = True
for i in list:
    arrow = Arrow(i[0],i[1],0,0,screen,SCREEN_WIDTH,SCREEN_HEIGHT)
    arrow.positionArrow()
    arrows.add(arrow)

while running:
    screen.fill((0,0,0))
    arrowleft.drawArrowPanel()
    arrowright.drawArrowPanel()
    arrowup.drawArrowPanel()
    arrowdown.drawArrowPanel()
    for arrow in arrows:
        if arrow.y < 500:
            arrow.arrowFall()
            arrow.positionArrow()
            collisionLeft = collisionDetect(arrow, arrowleft)
            collisionRight = collisionDetect(arrow, arrowright)
            collisionUp = collisionDetect(arrow, arrowup)
            collisionDown = collisionDetect(arrow, arrowdown)
        else:
            arrow.kill()

    pygame.display.update()

    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            running = False
            pygame.quit()
        if e.type == pygame.KEYDOWN and e.key == pygame.K_LEFT and collisionLeft:
            print "collided left"
        if e.type == pygame.KEYDOWN and e.key == pygame.K_RIGHT and collisionRight:
            print "collided right"
        if e.type == pygame.KEYDOWN and e.key == pygame.K_UP and collisionUp:
            print "collided up"
        if e.type == pygame.KEYDOWN and e.key == pygame.K_DOWN and collisionDown:
            print "collided down"

I left the class definitions out and can fetch them upon request. The event loop detects the down arrow being pressed during collision, but nothing else. Is there a quick fix for this? Is there a better way of handling it? Thank you.


Solution

  • Say you have 2 arrows.

    You iterate over all of them.

    The first one sets collisionLeft (or some other of this flags) to True, but then you check the second arrow in the same loop, and that arrow does not collide with arrowleft, so collisionLeft will be set to False.

    After that loop, you go on and check the key presses, but collisionLeft is False, even if the first arrow collides with arrowleft.

    I hope you see the problem.


    One solution is to store the collision flags in the arrows instead of four single variables, for example:

    ...
    for arrow in arrows:
        if arrow.y < 500:
            arrow.arrowFall()
            arrow.positionArrow()
            arrow.collisionLeft = collisionDetect(arrow, arrowleft)
            arrow.collisionRight = collisionDetect(arrow, arrowright)
            arrow.collisionUp = collisionDetect(arrow, arrowup)
            arrow.collisionDown = collisionDetect(arrow, arrowdown)
        else:
            arrow.kill()
    
    pygame.display.update()
    
    for e in pygame.event.get():
        ...
        if e.type == pygame.KEYDOWN:
            if e.key == pygame.K_LEFT:
                for arrow in (a for a in arrows if a.collisionLeft):
                    print "collided left " + str(arrow)
            if e.key == pygame.K_RIGHT:
                for arrow in (a for a in arrows if a.collisionRight):
                    print "collided right " + str(arrow)
            ...
    

    or something like that; you get the idea.