【问题标题】:Pygame colliderect causing issues with ball gamePygame 碰撞导致球赛出现问题
【发布时间】:2019-07-09 23:27:55
【问题描述】:

我正在制作推杆推杆游戏。我用类制作了墙壁和球,每个类都有一个定义其位置的矩形。所有的墙壁都在一个列表中,我使用 colliderect 检查列表以查看球是否击中任何墙壁。如果是这样,根据墙壁(垂直或水平),我改变球的方向。问题是偶尔,球会撞到墙上并卡在里面。我想它只是不断地与墙壁碰撞并不断改变方向,使其保持静止。

我尝试过添加冷却时间,但即使这样也并不总是有效。球的速度应该不是问题,就好像它每帧移动 3 像素一样,如果在其方向改变后在下一帧上以相同的速度移动。然而,较慢的速度有所帮助,但仍然不能完全解决这个问题。此外,我在每一帧上移动球之前检测碰撞。

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

【问题讨论】:

  • 如果球与墙壁相撞,然后将球向后移动一点,这样它只会碰到墙壁 - 如果它向左移动则ball.rect.left = wall.rect.right,如果它向右移动则ball.rect.right = wall.rect.left
  • 使用Sprite.Group(),您可以在没有for 循环的情况下一次检查所有墙壁的collisin。并且有一种方法,首先仅在 X 上移动球并检查所有墙壁(并最终将其向后移动一点),然后仅在 Y 上移动球并再次检查所有墙壁(并最终将其向后移动一点)。这样你就可以解决一些问题 - 即。如果你被困在角落里。
  • example你可以在update()看到这个方法。
  • 没有代码尝试解决它是没有意义的。我们猜不出问题出在哪里。
  • 我检查了代码。你有问题,因为你在两个地方有球的位置:(ball.x,ball.y)(ball.rect.x, ball.rect.y)。首先您移动球ball.x += ball.y_change,但稍后您使用ball.rect 中的旧位置检查碰撞。您应该只使用 ball.rect - ball.rect.x += ball.y_change 然后它可以正常工作,几乎是理想的。如果您减速到clock.tick(10),那么您会看到球没有进入墙内。有时它不会碰墙,但对ball.rect.left = wall.rect.right来说这是个问题

标签: python pygame collision-detection


【解决方案1】:

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

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)

这样你就可以确定一旦速度分量被翻转,它不会立即翻转回来。

【讨论】:

    【解决方案2】:

    尝试了所有建议的方法,但没有一个对我有用。放弃使用 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-21
      • 1970-01-01
      相关资源
      最近更新 更多