pythonlistclasspygamepgzero

Can't remove instances of a class


I starting to code in python and using pyzero to make a simple game. After the end of the game, I want to delete all the existing instances of certain types of classes, to allow the game to start again. I have a list of all the instances of that class, but using remove(self) seems to cause a problem in the logic that I can't work out.

class Ball(Actor):
    ball_list = []

    def __init__(self, actor):               
        Actor.initiate_actor(self,"ball")
        Ball.ball_list.append(self)
        self.alive = True

    def kill(self):
        if self.alive:
            self.alive = False
            Ball.ball_list.remove(self) 


def new_game():
    global game_over, score

    for actor in Ball.ball_list:
        actor.kill()

    score = 0
    game_over = False


def draw():
    global game_over
    if game_over:
        screen.clear()
        screen.draw.text("Game Over", center = (WIDTH/2, HEIGHT/2), color = 'white')

    else:
        screen.clear()
        backdrop.draw()  
        for actor in Ball.ball_list:
            if actor.alive:
                actor.draw()

Solution

  • Actually you remove objects from a list while you iterate through the list. Read How to remove items from a list while iterating?, for more information about this topic.

    Create a shallow copy of the list (Ball.ball_list[:], see More on Lists) and iterate trough the copy of the list, while you remove items from the original list:

    def new_game():
        global game_over, score
    
        for actor in Ball.ball_list[:]:
            actor.kill()
    
        score = 0
        game_over = False
    

    Anyway, since you want to remove all elements from the list it is sufficient to call clear()

    Ball.ball_list.clear()
    

    or to delete all the elements (see del)

    del Ball.ball_list[:]
    

    respectively to create a new and empty list

    Ball.ball_list = []
    

    Note, the memory of objects which are not used is freed by the garbage collection, thus it is sufficient to remove an object from (all) lists. Furthermore, it is not necessary to reset atributes of objects which will be destroyed.