Search code examples
pythonclassobjectpygamecollision-detection

How do I define collisions for x and y separately?


So in this function I have collision detection between a ball and a paddle and score (and other stuff that aren't relevant for this question) . When the ball hits the paddle it bounces off in the oposite direction. It works fine for the left side of the paddle, but if the ball hits from the top or the bottom it kinda slides and the score skyrockets.

def Objects (paddle,ball,hits,font,black):  
    if ball.BallRect.colliderect(paddle.PaddleRect):
        ball.vx *= -1
        score_text = font.render(f"Score: " + str(hits + 1),True, black)
        temp += 1
        
    else:
        score_text = font.render(f"Score: " + str(hits),True, black)
        window.blit(score_text,(20,20))
    
    return temp

Solution

  • See Sometimes the ball doesn't bounce off the paddle in pong game.

    When the ball hits the left paddle, the ball bounces to the right and the following x-direction must be positive. When the ball hits the right paddle, the ball bounces to the left and the following x-direction must be negative.
    Use abs(x) to compute the absolute value of a number. The new direction of the ball is either abs(ball.vx) or -abs(ball.vx).

    You have to distinguish between leftPaddle and rightPaddle

    if ball.BallRect.colliderect( leftPaddle.PaddleRect ):
        ball.vx = abs(ball.vx)
    
        # [...]
    
    elif ball.BallRect.colliderect( rightPaddle.PaddleRect ):
        ball.vx = -abs(ball.vx)
    
        # [...]
    

    Or you need to know which paddle is hit. Pass either "left" or "right" to the argument side:

    def Objects(paddle, side, ball, hits, font, black):  
        if ball.BallRect.colliderect(paddle.PaddleRect):
          
            if side == "left":
                ball.vx = abs(ball.vx)
            else:
                ball.vx = -abs(ball.vx)
        
          
            score_text = font.render(f"Score: " + str(hits + 1),True, black)
            temp += 1
            
        else:
            score_text = font.render(f"Score: " + str(hits),True, black)
            window.blit(score_text,(20,20))
        
        return temp
    

    If you only have 1 paddle, it is sufficient to set the correct direction. If you have just the right paddle:

    def Objects(paddle, ball, hits, font, black):  
        if ball.BallRect.colliderect(paddle.PaddleRect):
    
            ball.vx = -abs(ball.vx)
    
            score_text = font.render(f"Score: " + str(hits + 1),True, black)
            temp += 1
    
        else:
            score_text = font.render(f"Score: " + str(hits),True, black)
            window.blit(score_text,(20,20))
        
        return temp