PyGame collide_rect正在检测不存在的碰撞

时间:2019-02-21 23:44:16

标签: python pygame collision-detection

我还是pygame的新手,而且还是一般的编码。我正在制作需要碰撞检测的游戏,但似乎有问题。每次我运行程序时,它都会检测到不存在的冲突。这是我的代码中的一些片段:

class Player(pygame.sprite.Sprite):
    def __init__(self,x,y,width,height):
    pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.right = False
        self.left = False
        self.up = False
        self.down = False
        self.surf = pygame.Surface((50,50))
        self.rect = self.surf.get_rect()

    def draw(self):
        pygame.draw.rect(screen, (0,0,0), (self.x, self.y, self.width, self.height))

    def collision_test(self):
        if pygame.sprite.collide_rect(self, block1):
            print("a collision is detected")

以上是我的球员课。

class Block1(pygame.sprite.Sprite):
    def __init__(self,x,y,width,height):
        pygame.sprite.Sprite.__init__(self)
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.surf = pygame.Surface((self.width,self.height))
        self.rect = self.surf.get_rect()

    def draw(self):
        pygame.draw.rect(screen, (150,150,150), (self.x, self.y, self.width, self.height))

这是我的班级,我的球员应该与之相撞。我正在碰撞检测中运行打印命令以进行调试。就像我说的那样,即使它们不发生冲突,它也会不断打印我给它的消息。虽然没有错误消息。任何帮助,将不胜感激!在此先感谢:)

编辑:

我更改了冲撞测试方法并添加了block1参数。现在是这样:

    def collision_test(self, block1):
        if pygame.sprite.collide_rect(self, block1):
            print("a collision is detected")

我的播放器和block1精灵是在主循环之前启动的,看起来像这样:

player = Player(50,50,50,50)
block1 = Block1(200, 200, 100, 100)

我在mainloop的末尾调用函数crash_test。如果您需要它,这是我的完整代码:https://pastebin.com/LTQdLMuV

1 个答案:

答案 0 :(得分:2)

发生的事情是您忘记更新对象矩形的位置。

来自pygame docs

  

get_rect()
  获取表面的矩形区域
  get_rect(** kwargs)->矩形
  返回一个覆盖整个表面的新矩形。 此矩形将始终从0开始,宽度为0。和高度与图片相同。

PlayerBlock1两个类中,您都有一行:

self.rect = self.surf.get_rect()

要使用colliderect(),必须将rect属性更新为屏幕上图像的位置(以像素为单位),否则draw()使用的坐标之间将不匹配方法和用于检查碰撞的矩形。改为:

self.rect = self.surf.get_rect().move(x, y)

这样,当创建对象时,rect属性对应于对象在屏幕上的实际位置。

请记住在移动玩家方块时更新player.rect的位置。也可以编辑move_player()函数,例如通过添加:

player.rect.x = player.x
player.rect.y = player.y

使rect与屏幕上显示的内容相对应。

评论后编辑

如果您的目标是如何防止曲面之间的相互缠结,则操作会更加复杂。检测碰撞只是过程的一部分。完整的步骤是:

  • 移动播放器对象。
  • 不仅可以检测到碰撞,还可以检测到发生碰撞的侧面。
  • 一旦检测到侧面,请沿该轴向后移动玩家对象。
  • 重画。