Search code examples
pythonpygamecollision-detection

Pygame colliderect causing issues with ball game


I am making a putt putt game. I made the walls and the balls with classes and each class has a rect defining its position. All of the walls are in a list and I check the list using colliderect to see if the ball is hitting any of the walls. If so, depending on the wall (vertical or horizontal), I change the direction the ball is going. The problem is that occasionally, the ball will hit the wall and get stuck inside. I imagine that it is just continually colliding with the wall and keeps changing direction, making it just stay still.

Ive tried adding a cooldown, but even that doesn't always work. The speed of the ball shouldn't be the issue as if it moves 3px per frame, if would be moving that same speed out on the next frame after its direction was changed. However, slower speeds help but still dont completely solve this issue. Also, I am detection collisions before I move the ball on each frame.

for wall in walls:
    if wall.type == "hwall":
        if wall.rect.colliderect(ball.rect):
            ball.y_change = -(ball.y_change)
    elif wall.type == "vwall":
        if wall.rect.colliderect(ball.rect):
            ball.x_change = -(ball.x_change)

Here is the full code: https://pastebin.com/85Ge175i


Solution

  • Tried all methods suggested and none worked for me. Gave up on using the pygame colliderect feature as it doesnt seem to work for my specific needs. Instead I checked the ball position with all walls and manual got collision that way. Also upon collision I move the ball back a bit to prevent it getting stuck in walls.

    # Check for collision
    for wall in walls:
        if wall.type == "hwall":
    
            if ball.y_change < 0:
                if wall.rect.top <= ball.rect.top <= wall.rect.bottom and wall.rect.left <= ball.rect.center[0] <= wall.rect.right:
                    ball.y_change = -(ball.y_change)
                    ball.y += speed_y * 2
            else:
                if wall.rect.top <= ball.rect.bottom <= wall.rect.bottom and wall.rect.left <= ball.rect.center[0] <= wall.rect.right:
                    ball.y_change = -(ball.y_change)
                    ball.y -= speed_y * 2
    
    
        elif wall.type == "vwall":
    
            if ball.x_change < 0:
                if wall.rect.left <= ball.rect.left <= wall.rect.right and wall.rect.top <= ball.rect.center[1] <= wall.rect.bottom:
                    ball.x_change = -(ball.x_change)
                    ball.x += speed_x * 2
            else:
                if wall.rect.left <= ball.rect.right <= wall.rect.right and wall.rect.top <= ball.rect.center[1] <= wall.rect.bottom:
                    ball.x_change = -(ball.x_change)
                    ball.x -= speed_x * 2