Search code examples
pythonwhile-looppygamecollisionpong

Why does a certain if statement only trigger once in a while loop?


I'm trying to get into game programming but I'm having difficulty with the first game I'm making. I want to make a pong game, but I can't get the collision detection to work twice. It works once either way the ball goes, but the second time doesn't work. Here's my code:

    import pygame
    import random
    from random import uniform

class Game(object):
    def main(self, screen):

        rand = random.randint(100, 250)
        clock = pygame.time.Clock()
        icon = pygame.image.load('player.png').convert_alpha()
        image = icon
        ball = pygame.image.load('ball.png').convert_alpha() #10 x 10
        bar = pygame.image.load('bar.png').convert_alpha() # 25 x 200
        divider = pygame.image.load('divider.png').convert_alpha() # 8 x 40

        pressed_up = False
        pressed_down = False

        pressed_up2 = False
        pressed_down2 = False

        ballActive = False
        ballActive2 = False
        ballCollide = False
        ballCollide2 = False
        ballCanCollide = False
        ballCanCollide2 = False
        ballIsMovingControlled = False
        ballIsMovingControlled2 = False

        x = 0
        barY = 300
        barY2 = 300
        barHitX = 20
        barHitY = 200
        barHitX2 = 20
        barHitY2 = 200
        ballangle = 90
        ballAccel = 1
        ball_x = 530
        ball_y = 390

        white = (255, 255, 255)

        while 1:
            clock.tick(30)
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    return
                if event.type == pygame.KEYDOWN and event.key ==     pygame.K_ESCAPE:
                    return

                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_w:
                        pressed_up = True
                    if event.key == pygame.K_s:
                        pressed_down = True

                    if event.key == pygame.K_UP:
                        pressed_up2 = True
                    if event.key == pygame.K_DOWN:
                        pressed_down2 = True

                    if event.key == pygame.K_SPACE:
                        ballActive2 = True

                    if event.key == pygame.K_LEFT:
                        ballActive = False
                        ballActive2 = False
                        ballIsMovingControlled = True
                    if event.key == pygame.K_RIGHT:
                        ballActive = False
                        ballActive2 = False
                        ballIsMovingControlled2 = True

                elif event.type == pygame.KEYUP:
                    if event.key == pygame.K_w:
                        pressed_up = False
                    if event.key == pygame.K_s:
                        pressed_down = False

                    if event.key == pygame.K_UP:
                        pressed_up2 = False
                    if event.key == pygame.K_DOWN:
                        pressed_down2 = False
                    if event.key == pygame.K_LEFT:
                        ballActive = False
                        ballActive2 = False
                        ballIsMovingControlled = False
                    if event.key == pygame.K_RIGHT:
                        ballActive = False
                        ballActive2 = False
                        ballIsMovingControlled2 = False


            if pressed_up == True:
                barY -= 10
            if pressed_down == True:
                barY += 10

            if pressed_up2 == True:
                barY2 -= 10
            if pressed_down2 == True:
                barY2 += 10

            if ballActive == True:
                ball_x -= 5
                ball_y = 390
                print("moving")

                if ball_x == barHitX + 20 and ball_y >= barY and ball_y <= barY + 200:
                    ball_x = 32
                    ballActive = False
                    ballCollide = True
                    print("stopped1")

            if ballActive2 == True:
                ball_x += 5
                ball_y = 390
                print("moving2")

                if ball_x == barHitX2 + 1040 and ball_y >= barY2 and ball_y <= barY2 + 200:
                    ball_x = 1058
                    ballCollide2 = True
                    ballActive2 = False
                print("stopped2")

            if ball_x == 600:
                print("why wont you collide")

            if ballIsMovingControlled == True:
                ball_x -= 5
            if ballIsMovingControlled2 == True:
                ball_x += 5





            if ballCollide == True:
                ballActive2 = True
                print("stopping1")
                ballCollide = False
            if ballCollide2 == True:
                ballActive = True
                print("stopping2")
                ballCollide2 = False








            def blitLvl():
                ballBlit = screen.blit(ball, (ball_x, ball_y))
                barBlit = screen.blit(bar, (30, barY))
                barBlit2 = barBlit = screen.blit(bar, (1050, barY2))
                barHitBox = pygame.draw.rect(screen, white, (30, barY, barHitX, barHitY), 1)
                barHitBox2 = pygame.draw.rect(screen, white, (1050, barY2, barHitX2, barHitY2), 1)

                screen.blit(divider, (530,20))
                screen.blit(divider, (530,100))
                screen.blit(divider, (530,180))
                screen.blit(divider, (530,260))
                screen.blit(divider, (530,340))
                screen.blit(divider, (530,420))
                screen.blit(divider, (530,500))
                screen.blit(divider, (530,580))
                screen.blit(divider, (530,660))
                screen.blit(divider, (530,740))
                screen.blit(divider, (530,820))


                pygame.display.update()


            screen.fill((0, 0, 0))

            blitLvl()
            pygame.display.set_caption("Pong")
            pygame.display.set_icon(icon)
            pygame.display.flip()

if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode((1080, 800))
    Game().main(screen)

The problem stems from the part referencing when the ball is active. I check the collision of the left paddle when the ball is going left, and vice versa. One of them can trigger, but the other isn't recognized. It just goes straight through the paddle.

            if ballActive == True:
                ball_x -= 5
                ball_y = 390
                print("moving")

                if ball_x == barHitX + 20 and ball_y >= barY and ball_y <= barY + 200:
                    ball_x = 32
                    ballActive = False
                    ballCollide = True
                    print("stopped1")

            if ballActive2 == True:
                ball_x += 5
                ball_y = 390
                print("moving2")

                if ball_x == barHitX2 + 1040 and ball_y >= barY2 and ball_y <= barY2 + 200:
                    ball_x = 1058
                    ballCollide2 = True
                    ballActive2 = False
                    print("stopped2")

Solution

  • I think it is related to your conditional statement:

    if ball_x == barHitX2 + 1040 and ball_y >= barY2 and ball_y <= barY2 + 200:
        ball_x = 1058
    

    and incrementing by 5 and 10. I don't think you want to check if ball_x is exactly barHitX2 + 1040, but rather if ball_x is within a "barHitX2 range".

    (i.e.)

    if (ball_x >= BarHitX2 + 1040 and ball_x <= BarHitX2 + 1065) and (ball_y >= barY2 and ball_y <= barY2 + 200):
        ...
    

    That would be my guess at least.