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

Pygame精灵移动时出现残影(重叠)问题求助

Pygame精灵移动出现残影问题

我用Pygame开发时遇到了精灵重叠、出现残影的问题。Pygame通过while循环实现动画,我原本以为小球会正常下落,但运行后却留下了残影。

我的代码分为三部分:初始化游戏屏幕的设置部分、实现绿色圆形物理引擎的类部分、负责绘制精灵的while循环部分,代码如下:

import pygame as pg
import numpy as np

pg.init()
# screen = X_X
screen = pg.display.set_mode((400, 400))
pg.display.set_caption('movingcircle')
# width, height = oMo
width, height = pg.display.get_surface().get_size()
# running = P~~
running = True
# clock = X_X
clock = pg.time.Clock()
# wind, gravity = X_X
wind = np.array([1, 0])
gravity = np.array([0, 1])

class Circle:
    def __init__(self):
        #self.pos,vel = ~II
        self.surf = pg.image.load('movingcircle\\circle.png').convert_alpha()
        self.pos = np.array([width / 2, height / 2])
        self.vel = np.array([0, 0])
        self.acc = np.array([0, 0])
    def applyForce(self, force):
        if force == 'wind':
            self.acc += wind
        if force == 'gravity':
            self.acc += gravity
    def calculate(self):
        self.vel += self.acc
        self.pos += self.vel
        self.rect = self.surf.get_rect(midbottom = (self.pos[0], self.pos[1]))

    #def show(self):
        #screen.blit(self.surf, (self.rect.x, self.rect.y))

circle = Circle()

while running:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            running = False
    circle.applyForce(force = 'gravity')
    circle.calculate()
    #circle.show()
    print(circle.rect)
    screen.blit(circle.surf, circle.rect)
    pg.display.update()
    clock.tick(60)

问题原因

出现残影的核心是每帧绘制新精灵前未清除上一帧画面。Pygame的screen是一块画布,每次blit只是将新内容叠加在原有内容上,不清除的话旧精灵图像会残留,形成残影。

解决方法

  1. 清除上一帧画面:在每帧绘制精灵前,用纯色填充整个屏幕(或绘制背景图),添加代码:
    screen.fill((0, 0, 0))  # 黑色填充,可根据需求修改颜色
    
  2. 重置加速度:当前代码中加速度会持续叠加,导致小球速度无限制增加,不符合物理逻辑。在calculate()方法末尾添加:
    self.acc = np.array([0, 0])
    
  3. 优化代码结构:将绘制逻辑封装到Circle类的show()方法中,让代码更清晰。

修改后的完整代码

import pygame as pg
import numpy as np

pg.init()
screen = pg.display.set_mode((400, 400))
pg.display.set_caption('movingcircle')
width, height = pg.display.get_surface().get_size()
running = True
clock = pg.time.Clock()
wind = np.array([1, 0])
gravity = np.array([0, 1])

class Circle:
    def __init__(self):
        self.surf = pg.image.load('movingcircle\\circle.png').convert_alpha()
        self.pos = np.array([width / 2, height / 2])
        self.vel = np.array([0, 0])
        self.acc = np.array([0, 0])
    
    def applyForce(self, force):
        if force == 'wind':
            self.acc += wind
        if force == 'gravity':
            self.acc += gravity
    
    def calculate(self):
        self.vel += self.acc
        self.pos += self.vel
        self.rect = self.surf.get_rect(midbottom = (self.pos[0], self.pos[1]))
        self.acc = np.array([0, 0])  # 重置加速度
    
    def show(self):
        screen.blit(self.surf, self.rect)

circle = Circle()

while running:
    for event in pg.event.get():
        if event.type == pg.QUIT:
            running = False
    
    screen.fill((0, 0, 0))  # 清除上一帧画面
    circle.applyForce(force = 'gravity')
    circle.calculate()
    circle.show()
    
    pg.display.update()
    clock.tick(60)

内容的提问来源于stack exchange,提问作者kingyoon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 13:20:32