【问题标题】:Pygame sprite-collision detection doesnt workPygame精灵碰撞检测不起作用
【发布时间】:2019-06-15 12:39:43
【问题描述】:

当我尝试检测两个矩形之间的碰撞时 hit = pygame.sprite.groupcollide(enemy_sprites, player_sprites, 1, 1) 当我启动程序时它只打印一次“HIT”

我也尝试检测与 hit = pygame.sprite.spritecollide(player_sprites, enemy_sprites, 1) 但是出现了这个错误:

回溯(最近一次通话最后一次):
文件“D:/Python/PyCharm/test/src/Main/test.py”,第 104 行,在
hit = pygame.sprite.spritecollide(player_sprites,enemy_sprites,1)
spritecollide 中的文件“D:\Programme\python\lib\site-packages\pygame\sprite.py”,第 1523 行 ''''spritecollide = sprite.rect.colliderect AttributeError: 'Group' 对象没有属性 'rect'

    import pygame


class Player(pygame.sprite.Sprite):

    def __init__(self, x, y, width, height):
        pygame.sprite.Sprite.__init__(self)

        # def colours
        self.GREEN = (0, 255, 255)
        self.BLACK = (0, 0, 0)

        self.playerx = x
        self.playery = y
        self.playerW = width
        self.playerH = height
        self.vel = 5

        self.player_image = pygame.Surface((self.playerW, self.playerH))
        self.player_image.fill(self.GREEN)
        self.rect = self.player_image.get_rect()

    def handleKeys(self):
        keys = pygame.key.get_pressed()

        if keys[pygame.K_UP]:
            if self.playery >= self.vel:
                self.playery -= self.vel
        elif keys[pygame.K_DOWN]:
            if self.playery + 50 <= screenH - self.vel:
                self.playery += self.vel
        elif keys[pygame.K_LEFT]:
            if self.playerx >= self.vel:
                self.playerx -= self.vel
        elif keys[pygame.K_RIGHT]:
            if self.playerx + 50 <= screenW - self.vel:
                self.playerx += self.vel
        else:
            pass

    def drawPlayer(self, surface):
        player_sprites.update()

        surface.fill(self.BLACK)

        surface.blit(self.player_image, (self.playerx, self.playery))


class Enemy(pygame.sprite.Sprite):
    def __init__(self, x, y, width, height):
        pygame.sprite.Sprite.__init__(self)

        self.enemyX = x
        self.enemyY = y
        self.enemyW = width
        self.enemyH = height

        self.RED = (255, 0, 0)

        self.enemy_image = pygame.Surface((self.enemyW, self.enemyH))
        self.enemy_image.fill(self.RED)
        self.rect = self.enemy_image.get_rect()

    def drawEnemy(self, surface):
        enemy_sprites.update()

        surface.blit(self.enemy_image, (self.enemyX, self.enemyY))


# def some variables
pygame.init()

clock = pygame.time.Clock()

screenW = 500
screenH = 500
playerx = 200
playery = 200

wn = pygame.display.set_mode((screenW, screenH))
pygame.display.set_caption("Test program")

# player
player_sprites = pygame.sprite.Group()
player = Player(100, 100, 50, 50)
player_sprites.add(player)

# enemy
enemy_sprites = pygame.sprite.Group()
enemy = Enemy(200, 200, 50, 50)
enemy_sprites.add(enemy)

# main loop
run = True
while run:

    clock.tick(60)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    hit = pygame.sprite.groupcollide(enemy_sprites, player_sprites, 1, 1)

    if hit:
        print("HIT")
        hit = False

    player.handleKeys()
    player.drawPlayer(wn)
    enemy.drawEnemy(wn)

    pygame.display.flip()

pygame.quit()

【问题讨论】:

    标签: python pygame sprite collision-detection


    【解决方案1】:

    pygame.sprite.groupcollide 比较组中pygame.sprite.Sprite 对象中的.rect 属性。

    进一步注意,如果pygame.sprite.groupcollide() 的第二个和第三个参数不是False,那么在发生碰撞时精灵会被“杀死”并从组中移除。
    你可以通过False来避免这种情况:

    hit = pygame.sprite.groupcollide(enemy_sprites, player_sprites, False, False)
    

    您必须在位置初始化或更改时更新.rect 属性:

    class Player(pygame.sprite.Sprite):
    
        def __init__(self, x, y, width, height):
            pygame.sprite.Sprite.__init__(self)
    
            # [...]
    
            self.player_image = pygame.Surface((self.playerW, self.playerH))
            self.player_image.fill(self.GREEN)
            self.rect = self.player_image.get_rect()
    
            self.rect.topleft = (self.playerx, self.playery)  # <--- init .rect.topleft
    
        def handleKeys(self):
            keys = pygame.key.get_pressed()
    
            if keys[pygame.K_UP]:
            # [...]        
    
            self.rect.topleft = (self.playerx, self.playery) # <---- update .rect.topleft
    
    class Enemy(pygame.sprite.Sprite):
        def __init__(self, x, y, width, height):
            pygame.sprite.Sprite.__init__(self)
    
            # [...]
    
            self.enemy_image = pygame.Surface((self.enemyW, self.enemyH))
            self.enemy_image.fill(self.RED)
            self.rect = self.enemy_image.get_rect()
    
            self.rect.topleft = (self.enemyX, self.enemyY)   # <--- init .rect.topleft
    

    您也可以删除self.playerx、self.playery、self.enemyX 和self.enemyY,分别使用self.rect.x 代替seld.rect.y。见pygame.Rect。

    【讨论】:

    • 但它只打印 HIT 一次...有什么办法可以解决这个问题吗?
    • @HelpMe135 是的。 hit = pygame.sprite.groupcollide(enemy_sprites, player_sprites, False, False)。答案中的第二句话。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2017-09-14
    • 1970-01-01
    • 2019-11-05
    相关资源
    最近更新 更多