Fandomethor
Fandomethor

Reputation: 33

How do I delete displayed objects in python with pygame?

I'm trying to make asteroids drop from the top straight to the bottom of the screen and then disappear. To do this I have made multiple objects of class Asteroid, however I can't delete them afterwards.

A = []
while gameLoop:
...

a = Asteroid()
A.append(a)`

for i in A:
    i.move()
    if i.pos > dWidth:
         del i  # This doesn't remove the object

Is there any way to delete them?

Upvotes: 3

Views: 24587

Answers (2)

skrx
skrx

Reputation: 20438

In pygame your objects should usually be subclasses of pygame.sprite.Sprite and should be stored in sprite groups which allow you to update and render all contained sprites by calling the update and draw methods. You can remove the sprites from the corresponding groups by calling their kill method.

In this example I add Projectile sprites to the all_sprites group each frame and kill them if they are outside of the game_area rect. pygame.Rects have a contains method that you can use to check if one rect is inside of another rect. Alternatively, you can just check if the rect's x or y attributes are less than 0 or greater than the screen's width and height.

import random

import pygame as pg
from pygame.math import Vector2


class Projectile(pg.sprite.Sprite):

    def __init__(self, pos, game_area):
        super().__init__()
        self.image = pg.Surface((5, 5))
        self.image.fill(pg.Color('aquamarine2'))
        self.rect = self.image.get_rect(center=pos)
        self.vel = Vector2(2, 0).rotate(random.randrange(360))
        self.pos = Vector2(pos)
        self.game_area = game_area

    def update(self):
        self.pos += self.vel
        self.rect.center = self.pos
        if not self.game_area.contains(self.rect):
            self.kill()


def main():
    screen = pg.display.set_mode((640, 480))
    game_area = pg.Rect(60, 60, 520, 360)
    game_area_color = pg.Color('aquamarine2')
    clock = pg.time.Clock()
    all_sprites = pg.sprite.Group(Projectile(game_area.center, game_area))

    done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True

        all_sprites.add(Projectile(game_area.center, game_area))
        all_sprites.update()

        screen.fill((30, 30, 30))
        all_sprites.draw(screen)
        pg.draw.rect(screen, game_area_color, game_area, 2)

        pg.display.flip()
        clock.tick(60)


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()

Upvotes: 3

Adelin
Adelin

Reputation: 8199

You need to implement a delete method in the Asteroid class, and call i.delete() in your if condition.

How to delete depends on how they are shown in the first place.

Upvotes: 4

Related Questions