PianoPianist
PianoPianist

Reputation: 77

Pygame sprite not deleting itself

I am making a game and when the sprite "Bomb" goes under 450 on the y axis, it is supposed to be deleted.

import pygame
BLACK = (  0,   0,   0)
WHITE = (255, 255, 255)
RED   = (255,   0,   0)
GREY = (129, 129, 129)

class SpriteSheet(object):
    def __init__(self, file_name):
        self.sprite_sheet = pygame.image.load(file_name).convert()
    def get_image(self, x, y, width, height, colour):
        image = pygame.Surface([width, height]).convert()
        image.set_colorkey(colour)
        image.blit(self.sprite_sheet, (0, 0), (x, y, width, height))
        return image
class Bomb(pygame.sprite.Sprite):
    change_x =0
    change_y = 0
    def __init__(self):
        super().__init__()
        sprite_sheet = SpriteSheet("Untitled.png")
        self.image = sprite_sheet.get_image(2, 2, 48, 48, WHITE)
        self.rect = self.image.get_rect()
    def move(self, y):
        self.rect.y += y
        if self.rect.y > 450:
            self.kill()
        print (self.rect.y)
pygame.init()
screen_width = 1000
screen_height = 500
screen = pygame.display.set_mode([screen_width, screen_height])
pygame.display.set_caption("Game")
clock = pygame.time.Clock()
done = False
bomb  = Bomb()
all_sprites = pygame.sprite.Group()
all_sprites.add(bomb)
while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
    
    screen.fill(WHITE)
    all_sprites.draw(screen)
    bomb.move(2)
    clock.tick(60)
    pygame.display.flip()
pygame.quit()

(Note that I'm printing the y axis of the bomb to check if it's deleted or not.) I tried to use the "kill()" method, but what happens is, it does disappear, but the y axis continues to print, which I think is not supposed to happen.

I tried to use the kill() method in another piece of code. It gets deleted and the y axis stops printing. The only difference between the 2 codes is that in this one, I am blitting an image onto the screen to use as a sprite, and in that one, I am using "Rect" to make the sprite.

Can someone please guide me on what else can I do to permanently remove the sprite from the memory, or is it okay if the values of the y axis are printing all the time (the sprite should be deleted)?

Upvotes: 1

Views: 585

Answers (1)

sloth
sloth

Reputation: 101072

The kill() method does not magically remove objects from memory. All it does is removing a Sprite from all it's Groups.

So in your code, the bomb is no longer displayed because it's no longer in all_sprites after kill() is called. But you still have a reference to the object (bomb), and you still call the move function every frame on the object. So the print statement is executed.

What do you expect to happen to your bomb variable after you called kill()?

Usually, you should implement all sprite logic in a method called update, and not call this method directly, but via the group, too, like the draw method.

Something like this:

class Bomb(pygame.sprite.Sprite):
    change_x =0
    change_y = 0
    def __init__(self):
        super().__init__()
        sprite_sheet = SpriteSheet("Untitled.png")
        self.image = sprite_sheet.get_image(2, 2, 48, 48, WHITE)
        self.rect = self.image.get_rect()
        self.speed = 2
    def update(self, y):
        self.rect.y += self.speed
        if self.rect.y > 450:
            self.kill()
        print (self.rect.y)

...
all_sprites = pygame.sprite.Group()
all_sprites.add(Bomb())
while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
    
    screen.fill(WHITE)
    all_sprites.draw(screen)
    all_sprites.update()
    clock.tick(60)
    pygame.display.flip()
pygame.quit()

This way, after kill() is called, no references to the object remain (and the python runtime will remove it from memory eventually).

Upvotes: 2

Related Questions