简体   繁体   English

Pygame 从组中删除单个精灵

[英]Pygame remove a single sprite from a group

I am making a game and when the sprite goes under 100 on the x axis it is supposed to be deleted.我正在制作一个游戏,当精灵在 x 轴上低于 100 时,它应该被删除。 The sprites are all located in a class.精灵都位于一个类中。 When the first sprite reaches the end, it deletes the final sprite of the group instead of the first.当第一个精灵到达末尾时,它会删除该组的最后一个精灵而不是第一个。

Enemy Class敌人等级

class Enemy(pygame.sprite.Sprite): 
    def __init__(self,x,y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('Enemy.gif').convert()
        self.rect = self.image.get_rect(x=x, y=y)

    def update(self):
       self.rect.x -= 4

    def die(self):
        for enemy in EnemyList:
            if enemy.rect.x<100:
                 EnemyList.remove(enemy)

    def draw(self, DISPLAY):
        DISPLAY.blit(self.image, self.rect)

Main Loop (Part for enemy)主循环(敌人部分)

time = 0
while not Gameover: #Loop of the gameplay
if time in (0,50,100,150,200):
    enemy = Enemy(DIS_HEIGHT,random.randrange(0,DIS_HEIGHT)
    enemy.add(EnemyList)
EnemyList.update()
EnemyList.draw(DISPLAY)
enemy.die()
time +=1

I have a background and everything else works fine, I just cannot delete the correct sprite from the enemy group.我有一个背景,其他一切正常,我只是无法从敌人组中删除正确的精灵。

An easier way would be to use the Sprite method kill() which removes a sprite from all pygame.sprite.Group ´s it's currently in.一种更简单的方法是使用 Sprite 方法kill()从它当前pygame.sprite.Group的所有pygame.sprite.Group删除一个精灵。

def die(self):
    if self.rect.x < 100:
        self.kill()

Calling die() in your update() will allow you to check whether to kill your sprite every game loop, but given the amount of code in die() you could simply just move the code inside the update() .update()调用die()将允许您检查是否在每个游戏循环中杀死您的精灵,但考虑到die()的代码量,您可以简单地将代码移动到update() And based on your current code, your EnemyList is already a pygame.sprite.Group object, so no change is needed there.根据您当前的代码,您的EnemyList已经是一个pygame.sprite.Group对象,因此无需更改。

Your current die() method is quite hard for me to comprehend.你目前的die()方法对我来说很难理解。 You're creating an enemy which checks whether all enemies (itself and the other in the list) should die.您正在创建一个敌人,用于检查是否所有敌人(自身和列表中的另一个)都应该死亡。 So in your game loop you call the method from a single enemy in order to control all enemies.因此,在您的游戏循环中,您可以从单个敌人调用该方法以控制所有敌人。 In other words, you're creating identical objects with different responsibilities.换句话说,您正在创建具有不同职责的相同对象。 As a rule of thumb: an object's methods should change only its own states.根据经验:一个对象的方法应该只改变它自己的状态。

Lastly, the draw() method is unnecessary since the superclass defines the method exactly in the way you have.最后, draw()方法是不必要的,因为超类完全按照您的方式定义了该方法。 So removing yours would instead call draw() of pygame.sprite.Sprite .所以删除你的会改为调用pygame.sprite.Sprite draw()

You cannot remove items from a list while iterating over it:迭代时不能从列表中删除项目:

def die(self):
    for enemy in EnemyList:
        if enemy.rect.x<100:
             EnemyList.remove(enemy)

You could instead write something like this:你可以这样写:

def die(self):
     global EnemyList
     EnemyList = [enemy for enemy in EnemyList if enemy.rect.x>=100]

The global statement is needed so that the function can modify the EnemyList , which is outside its scope in this case.需要global语句,以便函数可以修改EnemyList ,在这种情况下它超出了它的范围。

Or store the enemies that you want to delete to another list, and then delete them afterwards.或者将您要删除的敌人存储到另一个列表中,然后再将其删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM