Pygame使用并发编程绘制背景时图层顺序异常如何解决?
问题根因
你出现图层错乱的核心原因是绘制操作的执行顺序不可控:
- 调用
executor.submit(draw)只是把填充背景的任务提交给了线程池,不会阻塞主线程执行 - 主线程会立刻执行
pygame.draw.rect画玩家矩形,此时线程池的surface.fill和主线程的矩形绘制谁先执行完全不确定:- 如果fill先执行:背景在底层,矩形在上层,显示正常
- 如果矩形先执行:fill会把整个画布覆盖,矩形被背景盖住,显示异常
另外补充:Pygame的原生Surface绘制操作本身不是线程安全的,跨线程直接操作同一个Surface很容易出现不可预期的渲染问题,是你后续开发需要注意的点。
修复方案(保留线程池复用设计)
下面的方案既保证图层顺序正确,还保留了你线程复用、独立线程处理绘制相关逻辑的设计:
方案1:控制绘制时序,保证背景先绘制完成
提交背景绘制任务后,等待任务执行完成再进行上层元素的绘制,确保图层顺序不会乱。修改后的代码如下:
import sys import pygame import threading from concurrent.futures import ThreadPoolExecutor pygame.init() # ---------------------------------------- # Variables # ---------------------------------------- width = 600 height = 600 square = pygame.Rect(100,100,100,100) surface = pygame.display.set_mode( (width, height) ) # 单线程线程池保证绘制任务串行执行,不会出现抢占 executor = ThreadPoolExecutor(max_workers=1) pygame.display.set_caption('Texto') font = pygame.font.SysFont("arial", 24) # ---------------------------------------- # Function # ---------------------------------------- def draw_background(): surface.fill((20, 210, 190)) # 可以把上层元素绘制也放进线程池,保证所有绘制任务串行按提交顺序执行 def draw_player(): pygame.draw.rect(surface,(100,100,100),square) # ---------------------------------------- # Loop # ---------------------------------------- while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # 按图层从底到高顺序提交绘制任务,单线程池会按提交顺序串行执行,保证顺序 future_bg = executor.submit(draw_background) future_bg.result() # 等待背景绘制完成再执行后续操作 future_player = executor.submit(draw_player) future_player.result() # 等待玩家绘制完成 pygame.display.update()
方案2:更合理的性能优化思路
如果你的初衷是用线程优化性能,不建议把Surface绘制操作放进线程,更合理的拆分逻辑是:
- 线程池只负责绘制前的计算逻辑:比如玩家坐标计算、碰撞检测、资源加载、文本渲染预处理等耗时的CPU计算任务
- 所有Surface绘制操作统一在主线程按图层顺序执行,既避免线程安全问题,也能保证图层顺序正确
这种拆分方式能真正发挥多线程的性能优势,同时不会出现渲染时序问题。
内容的提问来源于stack exchange,提问作者Br0k3nS0u1
相关产品推荐
相关产品推荐

