Pygame碰撞会导致球类游戏问题

时间:2019-07-09 23:27:55

标签: python pygame collision-detection

我正在制作推杆游戏。我用班级制作墙壁和球,每个班级都有一个定义其位置的矩形。所有的墙壁都在列表中,我使用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

2 个答案:

答案 0 :(得分:0)

一种快速的解决方案是不仅要检查碰撞,还要检查墙和球的矩形边缘的位置。
该代码应易于说明:

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)

这样,您可以确定一旦速度分量被翻转,也不会立即向后翻转。

答案 1 :(得分:0)

尝试了所有建议的方法,但没有一种对我有用。放弃使用pygame碰撞功能,因为它似乎无法满足我的特定需求。取而代之的是,我检查了所有墙壁的球位置,然后手动碰到了那条球。另外,在发生碰撞时,我会将球向后移一点以防止其卡在墙壁中。

# 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