【问题标题】:pygame rectangle collision detection does not workpygame矩形碰撞检测不起作用
【发布时间】:2019-04-24 17:51:05
【问题描述】:

我正在尝试在我的游戏中添加一个平台,这样一旦你击中它,玩家就会停留在平台上,直到它掉下来,在这种情况下它会掉到地上。跳跃确实有效,但碰撞没有

我尝试在下面添加一些典型类型的碰撞检测器,但它们都有缺点

class Platform:
    def __init__(self, x, y, background):
        self.xpos = x
        self.ypos = y
        self.picture = background
        self.picture = pygame.transform.scale(self.picture, (500, 100))
        self.rect = self.picture.get_rect()

    def draw(self):
        screen.blit(self.picture, (self.xpos, self.ypos))

class Player:
    def __init__(self, x, y, pic_one, pic_two, pic_three, pic_four):
        self.xpos = x
        self.ypos = y
        self.speed_y = 0
        self.speed_x = 0
        self.picture = pic_one
        self.picture_one = pic_one
        self.picture_two = pic_two
        self.picture_three = pic_three
        self.picture_four = pic_four
        self.on_ground = True
        self.picture = pygame.transform.scale(self.picture, (100, 100))
        self.rect = self.picture.get_rect()

    def update(self):
        self.xpos += self.speed_x
        self.ypos += self.speed_y

        GRAVITY = 0.9

        self.speed_y += GRAVITY  # Accelerate downwards.
        self.xpos += self.speed_x 
        self.ypos += self.speed_y


        if self.ypos >= 620:
            self.ypos = 620
            self.speed_y = 0
            self.on_ground = True


        if self.on_ground == True:
            self.speed_y = 0


    def jump(self):
        if self.on_ground:
            self.on_ground = False
            self.speed_y = -20#Makes you move upwards

    def draw(self):
        screen.blit(self.picture, (self.xpos, self.ypos))

    def is_collided_with(self, sprite):
        return self.rect.colliderect(sprite.rect)

player_one = Player(30, 600, player_one_first_pic)
wood_platform = Platform(400, 400, platform_pic)
while True:
    [...]

这是我尝试并使用过的典型冲突类型,但 if 语句似乎永远不会发生

if player_one.rect.bottom == wood_platform.rect.top:
    player_one.on_ground = True

我尝试过的另一个是检测矩形是否碰撞 并且即使矩形没有碰撞,if 语句也是 True

if player_one.is_collided_with(wood_platform):
     player_one.on_ground = True 

这个方法我不习惯,因为它不够

if player_one.ypos == 600:
    player_one.on_ground = True

我使用的方法的实际结果是玩家根本没有撞到木制平台

(如果您确实需要更多了解,这里有一张图表:) 检查碰撞,但似乎不起作用

if player_one.rect.y == wood_platform.rect.y:
        print(True)
        player_one.on_ground = True
        on_platform = True

    else:
        on_platform = False

每次更新后的变化

self.rect.x = self.xpos
self.rect.y = self.ypos

【问题讨论】:

    标签: python pygame collision-detection


    【解决方案1】:

    至于我的问题是你使用self.xpos,self.ypos 移动对象并且你不改变self.rect(self.rect.x,self.rect.y)中的值但是你使用self.rect 来检查碰撞.

    你必须设置

    self.rect.x = self.xpos
    self.rect.y = self.ypos 
    

    在检查碰撞之前。

    你必须对所有移动的物体都这样做。或许每次移动后都这样做比较好。


    您只能使用self.rect.x、self.rect.y(而不是self.xpos, self.ypos),但它只能保留整数值。您在重力中使用浮点值,self.rect.x、self.rect.y 将向下舍入位置并给出不那么平滑的动画。

    但不使用浮动重力或浮动速度的物体只能使用self.rect 来保持位置。

    【讨论】:

    • 所以如果我现在这样做 if player_one.rect.y(玩家一是对象)== wood_platform.rect.y 会起作用,因为那是我觉得最舒服的做法
    • 您可以做到 - 但如果您在每次移动中移动玩家超过一个像素,则可能无法正常工作。在某一时刻player_one.rect.y 可以小于wood_platform.rect.y(所以它不会发生碰撞),而在下一刻它可以大于wood_platform.rect.y(所以它会发生碰撞)并且== 不会捕捉到它。最好使用self.rect.colliderect(other.rect)。它还可以识别左侧/右侧的碰撞,或者当您跳跃并且玩家的头部触摸底部的平台时 - 因此它应该停止向上移动并开始向下移动。
    • 好的,我已经添加了上面的代码块,但这似乎仍然没有发生
    • 你在 Player 和 Platform 中使用 self.rect.x , self.rect.y 吗?
    • 是的,我可以确认我这样做了
    【解决方案2】:

    我在工作中经常遇到同样的问题。使用浮点数时检查数字是否相等可能会失败。您可以尝试更改此设置

    if player_one.rect.bottom == wood_platform.rect.top:
        player_one.on_ground = True
    

    到这里:

    margin = 0.001 # Whatever amount you feel comfy with.
    if wood_platform.rect.top*(1-margin) <= player_one.rect.bottom <= wood_platform.rect.top*(1+margin):
        player_one.on_ground = True
    

    【讨论】:

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