Pygame碰撞Bug

时间:2018-02-25 19:51:19

标签: python pygame flappy-bird-clone

我对pygame很新,遇到了一个我无法自行解决的错误。我正在尝试编写Flappy Bird游戏。问题是碰撞检测有效,但它也与我的精灵混淆。如果我设法在比赛时遇到第一个障碍,那么差距会随机重置。但差距应始终相同,只是在另一个位置。如果我删除碰撞检测,它完全正常。有什么想法吗?

import pygame    
import random      

randomy = random.randint(-150, 150)

class Bird(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.Surface((25,25))
        self.image.fill((255,255,255))
        self.rect = self.image.get_rect()
        self.rect.center = (100, 200)
        self.velocity = 0.05
        self.acceleration =0.4

    def update(self):
        self.rect.y += self.velocity
        self.velocity += self.acceleration
        if self.rect.bottom > 590:
            self.velocity = 0
            self.acceleration = 0                                


class Pipe1(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.Surface((85, 500))
        self.image.fill((255, 255, 255))
        self.rect = self.image.get_rect()
        self.rect.center = (500, randomy)
        self.randomyupdate = random.randint(-150, 150)

    def update(self):
        self.rect.x -= 2
        if self.rect.x < -90:
            self.randomyupdate = random.randint(-150, 150)
            self.rect.center = (450, self.randomyupdate)

class Pipe2(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.Surface((85, 500))
        self.image.fill((255, 255, 255))
        self.rect = self.image.get_rect()
        self.rect.center = (500, (randomy +640))

    def update(self):
        self.rect.x -= 2
        self.randomyupdate = Pipe1.randomyupdate
        if self.rect.x < -90:
            self.rect.center = (450, (self.randomyupdate + 640))


pygame.init()
pygame.mouse.set_visible(1)
pygame.key.set_repeat(1, 30)
pygame.display.set_caption('Crappy Bird')
clock = pygame.time.Clock()

Bird_sprite = pygame.sprite.Group()
Pipe_sprite = pygame.sprite.Group()
Bird = Bird()
Pipe1 = Pipe1()
Pipe2 = Pipe2 ()
Bird_sprite.add(Bird)
Pipe_sprite.add(Pipe1)
Pipe_sprite.add(Pipe2)


def main():
    running = True
    while running:
        clock.tick(60)
        screen = pygame.display.set_mode((400,600))
        screen.fill((0,0,0))
        Bird_sprite.update()
        Pipe_sprite.update()
        Bird_sprite.draw(screen)
        Pipe_sprite.draw(screen)
我正在谈论的界限:
        collide = pygame.sprite.spritecollideany(Bird, Pipe_sprite)
        if collide:
            running = False

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.event.post(pygame.event.Event(pygame.QUIT))
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    Bird.rect.y -= 85
                    Bird.velocity = 0.05
                    Bird.acceleration = 0.4
                    Bird.rect.y += Bird.velocity
                    Bird.velocity += Bird.acceleration
        pygame.display.flip()


if __name__ == '__main__':
    main()

1 个答案:

答案 0 :(得分:5)

这与碰撞检测无关,它与sprite组中sprite的顺序有关,因为精灵组在内部使用无序的字典(在Python版本中<3.6)。因此,如果Pipe1精灵在群组中排在第一位,游戏将正常运行,但如果Pipe2精灵首先出现,那么它的update方法也会先被调用,前一个randomyupdate Pipe1的1}用于设置精灵的新中心坐标。

要解决此问题,您可以将精灵组转换为有序组,例如

Pipe_sprite = pygame.sprite.OrderedUpdates()

或更新每帧Pipe2的矩形

def update(self):
    self.rect.x -= 2
    self.rect.centery = Pipe1.randomyupdate + 640

    if self.rect.x < -90:
        self.rect.center = (450, Pipe1.randomyupdate + 640)

此外,请移除全局randomy变量,并始终使用randomyupdate的{​​{1}}属性。