Pygame. Sprite is still drawing after killing itself
Question:
I want to remove the sprite and not display it on screen after click. The screenshot show that the sprite is successfully removed from the group, but it is still drawn on the screen. I would be happy to get help on this matter.
import pygame as pg
class Figure1(pg.sprite.Sprite):
def __init__(self, width: int, height: int):
super().__init__()
self.image = pg.Surface((width, height))
self.image.fill((0,0,0))
self.rect = self.image.get_rect()
class Game:
def __init__(self, main_surface: pg.Surface):
self.main_surface = main_surface
self.group = pg.sprite.Group()
self.main_sprite = Figure1(40,40)
self.group.add(self.main_sprite)
self.group.draw(self.main_surface)
self.selected = None
def btn_down(self, pos, btn):
if btn == 1:
if self.main_sprite.rect.collidepoint(pos):
print(self.group.sprites())
print(self.main_sprite.alive())
self.main_sprite.kill()
print(self.group.sprites())
print(self.main_sprite.alive())
self.group.draw(self.main_surface)
pg.init()
clock = pg.time.Clock()
screen = pg.display.set_mode((200,200))
screen.fill((100,100,100))
pg.display.update()
g = Game(screen)
run = True
while run:
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
run = False
if event.type == pg.MOUSEBUTTONDOWN:
g.btn_down(event.pos, event.button)
clock.tick(60)
pg.display.update()
Answers:
The sprite doesn’t disappear just because you stop drawing it. Of course, you need to clear the screen. You have to clear the screen in every frame. The typical PyGame application loop has to:
- limit the frames per second to limit CPU usage with
pygame.time.Clock.tick
- handle the events by calling either
pygame.event.pump()
or pygame.event.get()
.
- update the game states and positions of objects dependent on the input events and time (respectively frames)
- clear the entire display or draw the background
- draw the entire scene (
blit
all the objects)
- update the display by calling either
pygame.display.update()
or pygame.display.flip()
import pygame as pg
class Figure1(pg.sprite.Sprite):
def __init__(self, width: int, height: int):
super().__init__()
self.image = pg.Surface((width, height))
self.image.fill((0,0,0))
self.rect = self.image.get_rect()
class Game:
def __init__(self, main_surface: pg.Surface):
self.main_surface = main_surface
self.group = pg.sprite.Group()
self.main_sprite = Figure1(40,40)
self.group.add(self.main_sprite)
self.selected = None
def btn_down(self, pos, btn):
if btn == 1:
if self.main_sprite.rect.collidepoint(pos):
self.main_sprite.kill()
def draw(self):
self.group.draw(self.main_surface)
pg.init()
clock = pg.time.Clock()
screen = pg.display.set_mode((200,200))
g = Game(screen)
run = True
while run:
# limit the frames per second
clock.tick(60)
# handle the events and update objects
for event in pg.event.get():
if event.type == pg.QUIT:
run = False
if event.type == pg.MOUSEBUTTONDOWN:
g.btn_down(event.pos, event.button)
# clear the screen
screen.fill((100,100,100))
# draw the objects
g.draw()
# update the display
pg.display.update()
pg.quit()
I want to remove the sprite and not display it on screen after click. The screenshot show that the sprite is successfully removed from the group, but it is still drawn on the screen. I would be happy to get help on this matter.
import pygame as pg
class Figure1(pg.sprite.Sprite):
def __init__(self, width: int, height: int):
super().__init__()
self.image = pg.Surface((width, height))
self.image.fill((0,0,0))
self.rect = self.image.get_rect()
class Game:
def __init__(self, main_surface: pg.Surface):
self.main_surface = main_surface
self.group = pg.sprite.Group()
self.main_sprite = Figure1(40,40)
self.group.add(self.main_sprite)
self.group.draw(self.main_surface)
self.selected = None
def btn_down(self, pos, btn):
if btn == 1:
if self.main_sprite.rect.collidepoint(pos):
print(self.group.sprites())
print(self.main_sprite.alive())
self.main_sprite.kill()
print(self.group.sprites())
print(self.main_sprite.alive())
self.group.draw(self.main_surface)
pg.init()
clock = pg.time.Clock()
screen = pg.display.set_mode((200,200))
screen.fill((100,100,100))
pg.display.update()
g = Game(screen)
run = True
while run:
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
run = False
if event.type == pg.MOUSEBUTTONDOWN:
g.btn_down(event.pos, event.button)
clock.tick(60)
pg.display.update()
The sprite doesn’t disappear just because you stop drawing it. Of course, you need to clear the screen. You have to clear the screen in every frame. The typical PyGame application loop has to:
- limit the frames per second to limit CPU usage with
pygame.time.Clock.tick
- handle the events by calling either
pygame.event.pump()
orpygame.event.get()
. - update the game states and positions of objects dependent on the input events and time (respectively frames)
- clear the entire display or draw the background
- draw the entire scene (
blit
all the objects) - update the display by calling either
pygame.display.update()
orpygame.display.flip()
import pygame as pg
class Figure1(pg.sprite.Sprite):
def __init__(self, width: int, height: int):
super().__init__()
self.image = pg.Surface((width, height))
self.image.fill((0,0,0))
self.rect = self.image.get_rect()
class Game:
def __init__(self, main_surface: pg.Surface):
self.main_surface = main_surface
self.group = pg.sprite.Group()
self.main_sprite = Figure1(40,40)
self.group.add(self.main_sprite)
self.selected = None
def btn_down(self, pos, btn):
if btn == 1:
if self.main_sprite.rect.collidepoint(pos):
self.main_sprite.kill()
def draw(self):
self.group.draw(self.main_surface)
pg.init()
clock = pg.time.Clock()
screen = pg.display.set_mode((200,200))
g = Game(screen)
run = True
while run:
# limit the frames per second
clock.tick(60)
# handle the events and update objects
for event in pg.event.get():
if event.type == pg.QUIT:
run = False
if event.type == pg.MOUSEBUTTONDOWN:
g.btn_down(event.pos, event.button)
# clear the screen
screen.fill((100,100,100))
# draw the objects
g.draw()
# update the display
pg.display.update()
pg.quit()