pygame /精灵:暴徒碰撞

卢英格:

嗨,我最近开始进入pygame库并进行一些小项目。我正在做一个非常简单的游戏,您作为玩家必须躲避敌人。但是,当它们相互碰撞时,我想删除它们。我想到了以下代码,但是,它仅删除了一个小怪。小怪既存在于all_sprites中,也存在于mob_sprites中。我对sprite和pygame还是很陌生,所以这里可能存在一个愚蠢的错误,希望有人可以帮助我。

# check mob collision
for mob in mobs:
    temp_sprites.add(mob)
    mobs.remove(mob)
    collision = pg.sprite.groupcollide(temp_sprites, mobs, True, True)
    for col in collision:
        # score is just for the game
        score += col.size
    else:
        mobs.add(mob)
        all_sprites.add(mob)

    temp_sprites.remove(mob)
懒惰

您的第一个问题是使用for...else循环。else如果break在碰撞情况下使用for循环,则会执行部分,从而重新添加精灵。

您的代码的第二个问题是,虽然groupcollide可以正确地将精灵从其组中删除,但由于它们仍存储在您要遍历循环的列表中,因此它们将被读取for(迭代一个精灵组将在每个列表中创建一个新列表)时间)。

因此,您可以使用以下方式修复代码:

    for mob in mobs.sprites():
        
        if not mob.groups():
            # mob was already removed by a previous iteration of this loop
            continue

        temp_sprites.add(mob)
        mobs.remove(mob)
        collision = pygame.sprite.groupcollide(temp_sprites, mobs, True, True)
        for col in collision:
            # score is just for the game
            score += col.size
            break
        else:
            mobs.add(mob)
            all_sprites.add(mob)

        temp_sprites.remove(mob)

但我建议update改用sprite方法处理碰撞

def update(self):
    # whatever
    if pygame.sprite.spritecollide(self, self.mobs, True, collide_rect_not_self):
        self.kill()

在哪里self.mobs是对mobs的引用,并且collide_rect_not_self是对以下内容的简单包装pygame.sprite.collide_rect

def collide_rect_not_self(a, b):
    if a != b:
        return pygame.sprite.collide_rect(a, b)

这是一个完整的示例:

import random
import pygame

def collide_rect_not_self(a, b):
    if a != b:
        return pygame.sprite.collide_rect(a, b)

class Actor(pygame.sprite.Sprite):
    def __init__(self, pos, mobs, static, *grps):
        super().__init__(mobs, *grps)
        self.image = pygame.Surface((40, 40))
        self.rect = self.image.get_rect(center=pos)
        self.pos = pygame.Vector2(*pos)
        self.vel = pygame.Vector2(random.randint(0, 10), random.randint(0, 10)) if not static else pygame.Vector2(0, 0)
        self.mobs = mobs

    def update(self):
        self.pos += self.vel
        if not pygame.display.get_surface().get_rect().contains(self.rect):
            self.vel *= -1
            self.rect.clamp_ip(pygame.display.get_surface().get_rect())
            self.pos = self.rect.center
        self.rect.center = self.pos
        if pygame.sprite.spritecollide(self, self.mobs, True, collide_rect_not_self):
            self.kill()

def main():
    pygame.init()
    clock = pygame.time.Clock()
    screen = pygame.display.set_mode((800, 600))
    mobs = pygame.sprite.Group()
    all_sprites = pygame.sprite.Group()
    while True:

        for event in pygame.event.get():
            pos = pygame.mouse.get_pos()
            if event.type == pygame.QUIT:
                return

            if event.type == pygame.MOUSEBUTTONDOWN:
                Actor(event.pos, mobs, event.button == 1, all_sprites)
                    
        screen.fill((255, 255, 255))
        all_sprites.update()
        all_sprites.draw(screen)
        clock.tick(30)
        
               
        pygame.display.flip()
main()

使用鼠标左键放置静态矩形,使用其他鼠标键放置移动的矩形。

在此处输入图片说明

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章