pygame矩形碰撞检测不起作用

时间:2019-04-24 17:51:05

标签: python pygame collision-detection

我正尝试在游戏中添加一个平台,以便一旦您点击它,玩家便会停留在平台上直到它掉落,在这种情况下它将落到地面上。跳跃确实有效,但碰撞无效

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

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

我使用的方法的实际结果是,播放器根本没有与木制平台发生碰撞

(如果您确实需要更多了解,请参见以下图表:) player_platform 检查碰撞,但似乎不起作用

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

2 个答案:

答案 0 :(得分:2)

对于我来说,问题是您使用self.xposself.ypos移动对象,而没有更改self.rectself.rect.xself.rect.y中的值),但您使用self.rect检查碰撞。

您必须设置

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

在检查碰撞之前。

您必须对所有移动的对象执行此操作。也许每走一步之后最好这样做。


您只能使用self.rect.xself.rect.y(而不是self.xpos, self.ypos),但是它只能保留整数值。您在重力中使用浮点值,而self.rect.xself.rect.y会舍入位置并产生不那么平滑的动画。

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

答案 1 :(得分:0)

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

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