Pygame colliderect 导致球类游戏出现问题
Pygame colliderect causing issues with ball game
我正在制作推杆推杆游戏。我用 classes 制作了墙壁和球,每个 class 都有一个定义其位置的矩形。所有的墙都在一个列表中,我使用 colliderect 检查列表以查看球是否击中了任何墙壁。如果是这样,根据墙壁(垂直或水平),我改变球的运动方向。问题是偶尔,球会撞到墙上并卡在里面。我想象它只是不断地与墙壁碰撞并不断改变方向,使其保持静止。
我试过添加冷却时间,但即使那样也不一定奏效。球的速度应该不是问题,因为它每帧移动 3px,如果在方向改变后在下一帧以相同的速度移动。然而,较慢的速度有帮助但仍不能完全解决这个问题。另外,我在每一帧移动球之前检测碰撞。
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)
完整代码如下:
https://pastebin.com/85Ge175i
一个快速的解决方案可能是不仅要检查碰撞,还要检查墙和球的矩形边缘的位置。
代码应该是不言自明的:
for wall in walls:
if wall.rect.colliderect(ball.rect):
if wall.type == "hwall" and wall.rect.bottom < ball.rect.bottom and ball.y_change > 0:
ball.y_change = -(ball.y_change)
elif wall.type == "hwall" and wall.rect.top > ball.rect.top and ball.y_change < 0:
ball.y_change = -(ball.y_change)
elif wall.type == "vwall" and wall.rect.right < ball.rect.right and ball.x_change > 0:
ball.x_change = -(ball.x_change)
elif wall.type == "vwall" and wall.rect.left > ball.rect.left and ball.x_change < 0:
ball.x_change = -(ball.x_change)
这样你就可以确保一旦速度分量被翻转,它不会立即翻转回来。
尝试了所有建议的方法,none 对我有用。放弃使用 pygame colliderect 功能,因为它似乎无法满足我的特定需求。相反,我检查了所有墙壁上的球位置,然后手动以这种方式发生碰撞。同样在碰撞时我将球向后移动一点以防止它卡在墙上。
# 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
我正在制作推杆推杆游戏。我用 classes 制作了墙壁和球,每个 class 都有一个定义其位置的矩形。所有的墙都在一个列表中,我使用 colliderect 检查列表以查看球是否击中了任何墙壁。如果是这样,根据墙壁(垂直或水平),我改变球的运动方向。问题是偶尔,球会撞到墙上并卡在里面。我想象它只是不断地与墙壁碰撞并不断改变方向,使其保持静止。
我试过添加冷却时间,但即使那样也不一定奏效。球的速度应该不是问题,因为它每帧移动 3px,如果在方向改变后在下一帧以相同的速度移动。然而,较慢的速度有帮助但仍不能完全解决这个问题。另外,我在每一帧移动球之前检测碰撞。
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)
完整代码如下: https://pastebin.com/85Ge175i
一个快速的解决方案可能是不仅要检查碰撞,还要检查墙和球的矩形边缘的位置。
代码应该是不言自明的:
for wall in walls:
if wall.rect.colliderect(ball.rect):
if wall.type == "hwall" and wall.rect.bottom < ball.rect.bottom and ball.y_change > 0:
ball.y_change = -(ball.y_change)
elif wall.type == "hwall" and wall.rect.top > ball.rect.top and ball.y_change < 0:
ball.y_change = -(ball.y_change)
elif wall.type == "vwall" and wall.rect.right < ball.rect.right and ball.x_change > 0:
ball.x_change = -(ball.x_change)
elif wall.type == "vwall" and wall.rect.left > ball.rect.left and ball.x_change < 0:
ball.x_change = -(ball.x_change)
这样你就可以确保一旦速度分量被翻转,它不会立即翻转回来。
尝试了所有建议的方法,none 对我有用。放弃使用 pygame colliderect 功能,因为它似乎无法满足我的特定需求。相反,我检查了所有墙壁上的球位置,然后手动以这种方式发生碰撞。同样在碰撞时我将球向后移动一点以防止它卡在墙上。
# 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