如何在Pygame的while循环中仅实例化一次Image类并正确调用?
问题修复方案
问题1:持续添加新Image实例的解决
你现在每帧调用draw_image()时,都会执行all_images.append(Image(...)),相当于每帧都新建一个图像实例,列表自然会无限膨胀。解决思路是把图像实例的创建和绘制逻辑分开:
- 先在循环外(初始化阶段)创建所有需要的Image实例,添加到
all_images列表里 - 在while循环内只调用绘制/更新逻辑,不再创建新实例
修改后的绘制函数只负责触发已有实例的更新和绘制:
def draw_all_images(): # 只更新并绘制已有的图像实例,不再创建新的 for image in all_images: image.run()
在初始化阶段(while循环前)创建图像实例(仅执行一次):
all_images = [] # 示例:创建一个初始位置(100,200)的图像实例 all_images.append(Image(my_image, (100, 200), draw_img=True, camera=True))
在while循环内只调用绘制函数:
while running: # 这里放事件处理、玩家输入等游戏逻辑 draw_all_images() pygame.display.flip() # 以pygame为例,刷新屏幕
问题2:位置修改被重置的解决
位置被重置是因为每帧都新建Image实例,__init__方法会重新把self.x、self.y设为初始的xy参数,之前run()里修改的位置直接被覆盖。上面的方案已经解决了这个问题——实例只创建一次,__init__仅执行一次,后续每帧只会调用run()更新位置,不会重置。
另外,你的Image类还有几个小问题需要修正:
class Image: def __init__(self, image, xy, draw_img=True, camera=False): self.image = image self.x = xy[0] # 直接用元组索引,不用转成list self.y = xy[1] self.draw_img = draw_img self.camera = camera def run(self): # 修正global语句的语法,把所有全局变量列全 global col_up, col_down, col_left, col_right, right_speed, left_speed, up_speed, down_speed global left_key, up_key, down_key, jump_velocity, run_once6, run_once3, jumped, time, last_time global change_x, player_speed, change_y # 先处理相机移动的位置更新 if self.camera: if change_x == 'x-': self.x += player_speed elif change_x == 'x+': self.x -= player_speed if change_y == 'y-': self.y += player_speed elif change_y == 'y+': self.y -= player_speed # 统一绘制逻辑,避免重复判断 if self.draw_img: screen.blit(self.image, (self.x, self.y))
总结
核心就是分离实例创建和帧更新逻辑:初始化阶段创建所有图像,每帧只更新它们的状态并绘制,不要每帧都新建实例。这样既不会导致列表无限增长,也不会重置图像位置。
内容的提问来源于stack exchange,提问作者Morris El Helou
相关产品推荐
相关产品推荐

