You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pygame Sprite调用kill()后仍在屏幕绘制的问题求助

问题:点击移除Sprite后仍显示在屏幕上

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

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:

  1. 删除Game.__init__里的self.group.draw(self.main_surface),不要在初始化时直接绘制
  2. 在主循环中,每次先填充屏幕背景,再调用group.draw绘制当前存在的Sprite
  3. 点击时只需要调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 10:10:34