Pygame中的Platformer碰撞

时间:2013-11-15 17:20:19

标签: python pygame collision-detection

我试图在Pygame中写一个平台游戏,但过去几周我一直坚持英雄和平台之间的碰撞检测。这是我的课程:

class Platform(object):
    def __init__(self, colour, rect):
        self.colour = colour
        self.rect = rect

    def draw(self, screen):
        pygame.draw.rect(screen, self.colour, self.rect)


class Character(Block):
    def __init__(self, colour, rect, speed):
        super().__init__(colour, rect)
        (self.dx, self.dy) = speed
        self.is_falling = True

    def update(self, platforms):
        self.is_falling = True
        for platform in platforms:
            if self.is_on(platform):
                self.rect.bottom = platform.rect.top
                self.dy = 0
                self.is_falling = False

        if self.is_falling:
            self.gravity()
        self.rect.x += self.dx
        self.rect.y += self.dy

    def is_on(self, platform):
        return (pygame.Rect(self.rect.x, self.rect.y + self.dy,
                            self.rect.width, self.rect.height)
                .colliderect(platform.rect) and self.dy > 0)

    def left(self):
        self.dx = -5

    def right(self):
        self.dx = 5

    def stop_x(self):
        self.dx = 0

    def jump(self):
        if self.dy == 0:
            self.dy = -25

    def gravity(self):
        self.dy += 5

这是我的职能:

def key_down(event, character):
    if event.key == pygame.K_LEFT:
        character.left()
    elif event.key == pygame.K_RIGHT:
        character.right()
    elif event.key == pygame.K_UP:
        character.jump()

def key_up(event, character):
    if event.key in (pygame.K_LEFT, pygame.K_RIGHT):
        character.stop_x()

def main():
    pygame.init()
    screen = pygame.display.set_mode((640, 480))
    pygame.display.set_caption("PyPlatformer")
    hero = Character((255, 255, 0), pygame.Rect(100, 0, 20, 20), (0, 0))
    platform1 = Block((0, 255, 255), pygame.Rect(100, 100, 100, 10))
    platform2 = Block((0, 255, 255), pygame.Rect(150, 150, 100, 10))
    platforms = (platform1, platform2)
    clock = pygame.time.Clock()
    while True:
        clock.tick(60)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                key_down(event, hero)
            elif event.type == pygame.KEYUP:
                key_up(event, hero)

        screen.fill((0, 0, 0))
        hero.update(platforms)
        [platform.draw(screen) for platform in platforms]
        hero.draw(screen)
        pygame.display.update()

然而,当Character位于Block时,碰撞检测失败,并且角色会通过该块。但是,当它移动并且在块内时,检测成功并且角色返回坐在块上。然后这个循环重复,角色看起来像是在块上弹跳。

导致此错误的原因是什么?我该如何解决?

1 个答案:

答案 0 :(得分:0)

此版本适用于我:

def is_on(self, platform):
    return (pygame.Rect(self.rect.x, self.rect.y + self.dy+1, # +1
                        self.rect.width, self.rect.height)
            .colliderect(platform.rect)) 

我添加+1并删除dy > 0


顺便说一句:我发现了其他问题。

如果您将平台放得太近(请参阅128中的platform2

platform1 = Block((0, 255, 255), pygame.Rect(100, 100, 100, 10))
platform2 = Block((0, 255, 255), pygame.Rect(150, 128, 100, 10)) # 128

站在platform2上的玩家可以触摸platform1,他会被platform1

移动

它可以让我真的很高兴:)

platforms = []
platforms.append(Block((0, 255, 255), pygame.Rect(100, 400, 100, 10)))
platforms.append(Block((0, 255, 255), pygame.Rect(150, 428, 100, 10)))
platforms.append(Block((0, 255, 255), pygame.Rect(250, 28, 10, 400)))
相关问题