报错:'pygame.Surface'对象无'update'属性,求排查代码问题
问题根源
你的报错核心原因是:particlelist里存储的是pygame.Surface对象(也就是你的self.img),但你在update方法里循环调用i.update(),而pygame.Surface根本没有update方法。
你混淆了「粒子发射器」和「单个粒子」的职责:当前的Createparticle类既做了发射器的工作,又试图把Surface当作粒子来处理,这就导致了类型错误。
修复方案
重构代码,拆分出「单个粒子」类和「粒子发射器」类,让各自职责清晰:
- 先定义单个粒子的
Particle类,每个粒子拥有自己的位置、速度、缩放、透明度等属性,以及update和draw方法; - 让
Createparticle作为发射器,负责生成和管理多个Particle实例,而不是直接操作Surface。
修复后的完整代码:
import pygame import random # 假设你有scale函数,这里补一个示例实现 def scale(surface, scale_factor): width = int(surface.get_width() * scale_factor) height = int(surface.get_height() * scale_factor) return pygame.transform.scale(surface, (width, height)) pygame.init() screen = pygame.display.set_mode((1000, 600)) FPS = 60 clock = pygame.time.Clock() # 假设basisbild是一个加载好的Surface,这里用纯色图示例 basisbild = pygame.Surface((20,20)) basisbild.fill((255,200,100)) class Particle: def __init__(self, x, y, img): self.x = x self.y = y self.scale_k = 0.1 self.img = scale(img, self.scale_k) self.alpha = 255 self.alpha_rate = 3 self.alive = True self.vx = 0 self.vy = 4 + random.randint(-10, 10) / 10 self.k = 0.01 * random.random() * random.choice([-1, 1]) def update(self): # 更新粒子的运动状态 self.x += self.vx self.vx += self.k self.y -= self.vy self.vy *= 0.99 # 更新缩放和透明度 self.scale_k += 0.005 self.img = scale(self.img, self.scale_k) self.alpha -= self.alpha_rate self.img.set_alpha(self.alpha) # 判断粒子是否存活 if self.alpha <= 0: self.alive = False def draw(self, screen): rect = self.img.get_rect(center=(self.x, self.y)) screen.blit(self.img, rect) class Createparticle: def __init__(self, xx, yy, img): self.x = xx self.y = yy self.img = img self.particlelist = [] self.verzoegerung = 0 def update(self): # 清理死亡的粒子 self.particlelist = [p for p in self.particlelist if p.alive] # 每隔一定帧数生成新粒子 self.verzoegerung += 1 if self.verzoegerung % 2 == 0: self.verzoegerung = 0 self.particlelist.append(Particle(self.x, self.y, self.img)) # 更新每个存活的粒子 for particle in self.particlelist: particle.update() def draw(self, screen): for particle in self.particlelist: particle.draw(screen) createparticle = Createparticle(500,300,basisbild) while True: # 处理退出事件,避免程序卡死 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() screen.fill((0, 0, 0)) createparticle.update() createparticle.draw(screen) pygame.display.update() clock.tick(FPS)
关键修复点
- 拆分出
Particle类:每个粒子是独立的实例,拥有自己的update方法,负责更新自身的运动、缩放、透明度和存活状态; Createparticle作为发射器:只负责生成新粒子、清理死亡粒子,以及调用所有粒子的update和draw方法;- 移除了原代码中对Surface调用
update的错误逻辑,不再把Surface直接放进粒子列表; - 补充了退出事件处理,避免程序无法正常关闭。
内容的提问来源于stack exchange,提问作者Joachim
相关产品推荐
相关产品推荐

