【问题标题】:PyGame collide_rect is detecting a non-existent collisionPyGame collide_rect 正在检测不存在的碰撞
【发布时间】:2019-02-21 23:44:15
【问题描述】:

我对 pygame 和一般的编码还是很陌生。我正在制作一款需要碰撞检测的游戏,但我似乎遇到了问题。每次我运行我的程序时,它都会检测到不存在的碰撞。以下是我的代码中的一些 sn-ps:

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)

我在主循环结束时调用函数collision_test。如果您需要,这里是我的完整代码:https://pastebin.com/LTQdLMuV

【问题讨论】:

  • 您好!您的 collision_test(self) 方法不接受任何 block1 参数。 block1 来自哪里?你在代码中的什么地方调用了这个函数?请添加您从类中实例化对象并使用它们的代码部分。
  • 感谢您的快速回复!刚刚编辑了我的帖子。就像我说的,我是编码新手,因此是 stackoverflow 的新手,所以我不确定在我编辑时您是否会收到通知。
  • 感谢更新,我想我找到了问题所在。我会写在答案中

标签: python pygame collision-detection


【解决方案1】:

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

来自pygame docs

get_rect()
获取 Surface 的矩形区域
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 对应于您在屏幕上的内容。

在 cmets 之后编辑

如果您的目标是如何防止表面之间的重叠,那就更复杂了。检测碰撞只是该过程的一部分。完整的步骤是:

  • 移动播放器对象。
  • 不仅检测是否存在碰撞,还检测碰撞的侧面。
  • 一旦检测到侧面,将玩家对象移回该轴上。
  • 重绘。

【讨论】:

  • 这就是问题所在,谢谢!但我想我的问题不够具体......它现在正在检测应该的碰撞,但我怎样才能使用它,这样我的播放器就不能重叠到 block1 中?我不知道如何让它成为我的球员无法通过的障碍。我想我可能需要一种方法来测试玩家在哪一侧重叠,以便我可以立即将玩家移出 block1。
  • 这是一个完全不同的问题,对于stackoverflow来说可能太宽泛了。我将在答案中添加一些提示,
  • 尝试执行这些步骤,如果您遇到一些困难,您可以针对该特定点提出问题。
  • 好的,我想我可能能够通过逻辑来解决它。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-10
相关资源
最近更新 更多