Pygame Sprite调用kill()后仍在屏幕绘制的问题求助
问题:点击移除Sprite后仍显示在屏幕上
我希望点击Sprite后将其移除,不再显示在屏幕上。截图显示Sprite已成功从Group中移除,但它仍会被绘制在屏幕上,恳请帮助解决这个问题。

原代码
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()
问题原因
Pygame的屏幕是像素缓冲区,之前绘制的Sprite像素会一直保留在屏幕上,除非用新的像素(比如背景色)覆盖。你的代码只在初始化和点击时绘制Group,但没有定期刷新背景,所以移除Sprite后,旧的图像依然留在屏幕上。另外,初始化时直接调用group.draw的方式也不符合Pygame的常规渲染流程。
解决方法
把渲染逻辑移到主循环中,每次循环先填充背景,再绘制所有Sprite:
- 删除
Game.__init__里的self.group.draw(self.main_surface),不要在初始化时直接绘制 - 在主循环中,每次先填充屏幕背景,再调用
group.draw绘制当前存在的Sprite - 点击时只需要调用
kill()移除Sprite,不需要额外调用group.draw
修改后的代码
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): print(self.group.sprites()) print(self.main_sprite.alive()) self.main_sprite.kill() print(self.group.sprites()) print(self.main_sprite.alive()) pg.init() clock = pg.time.Clock() screen = pg.display.set_mode((200,200)) 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) # 渲染流程:先填充背景,再绘制Sprite screen.fill((100,100,100)) g.group.draw(screen) clock.tick(60) pg.display.update()
这样修改后,每次主循环都会用背景色覆盖整个屏幕,然后只绘制当前Group中存在的Sprite。当你点击Sprite调用kill()后,Group里没有了这个Sprite,下一次循环就不会再绘制它,屏幕上的旧图像也会被背景色覆盖,达到移除后不再显示的效果。
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

