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

如何在Python类中实现Pygame游戏加载屏与资源加载并行运行?

实现Pygame加载资源时同步显示动画加载屏

嘿,我明白你想实现的是加载资源时同步展示动画加载屏的需求,用multiprocessing确实容易踩坑——因为Pygame的渲染上下文是绑定在主线程的,子进程没法直接操作窗口,很容易出现崩溃或者动画不显示的问题。下面给你两种靠谱的实现思路,都能完美搞定这个需求:

方法一:使用threading线程(推荐)

把资源加载逻辑放到子线程中执行,主线程专注于渲染加载屏动画,通过共享变量来跟踪加载进度,这样两者就能同时运行了。

完整代码示例

import pygame
import threading
import time

class Game:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((800, 600))
        self.clock = pygame.time.Clock()
        self.loading_done = False
        self.loading_progress = 0  # 加载进度0-100

        # 启动资源加载线程
        self.load_thread = threading.Thread(target=self.load_assets)
        self.load_thread.start()

        # 主线程运行加载屏动画
        self.loading_screen()

        # 加载完成后进入游戏主循环
        self.main_game_loop()

    def loading_screen(self):
        while not self.loading_done:
            # 处理退出事件
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    exit()

            # 绘制加载屏背景
            self.screen.fill((30, 30, 30))

            # 绘制进度条(示例动画)
            bar_width = 400
            bar_height = 40
            progress_width = int(bar_width * (self.loading_progress / 100))
            pygame.draw.rect(self.screen, (60, 60, 60), (200, 280, bar_width, bar_height))
            pygame.draw.rect(self.screen, (0, 255, 0), (200, 280, progress_width, bar_height))

            # 绘制加载文本
            font = pygame.font.Font(None, 36)
            text = font.render(f"Loading... {self.loading_progress}%", True, (255, 255, 255))
            self.screen.blit(text, (320, 230))

            # 更新屏幕
            pygame.display.flip()
            self.clock.tick(60)  # 保持60帧

    def load_assets(self):
        # 模拟加载大资源,实际替换成你的资源加载逻辑
        assets_to_load = ["texture1.png", "sound1.wav", "level1.json", "font.ttf"]
        total_assets = len(assets_to_load)

        for idx, asset in enumerate(assets_to_load):
            # 这里替换成真实的资源加载代码,比如pygame.image.load()等
            print(f"Loading {asset}...")
            time.sleep(0.5)  # 模拟加载耗时

            # 更新加载进度
            self.loading_progress = int((idx + 1) / total_assets * 100)

        # 标记加载完成
        self.loading_done = True

    def main_game_loop(self):
        print("进入游戏主循环!")
        running = True
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False

            self.screen.fill((0, 0, 255))
            font = pygame.font.Font(None, 48)
            text = font.render("游戏加载完成!", True, (255, 255, 255))
            self.screen.blit(text, (250, 270))
            pygame.display.flip()
            self.clock.tick(60)

        pygame.quit()

if __name__ == "__main__":
    Game()

关键注意点

  • 用threading.Thread把load_assets放到子线程,避免阻塞主线程的渲染
  • 通过self.loading_done和self.loading_progress两个共享变量同步状态,这两个变量是线程安全的(因为只是简单的赋值和读取操作)
  • 主线程在loading_screen中持续处理事件、渲染动画,直到loading_done变为True

方法二:分帧加载资源(无线程,适合简单场景)

如果不想用线程,可以把资源加载拆分成多个小步骤,每帧加载一小部分,同时更新加载屏动画。这种方法完全在主线程运行,没有线程安全问题。

简化代码示例

import pygame

class Game:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((800, 600))
        self.clock = pygame.time.Clock()
        self.asset_loader = self.load_assets_generator()
        self.loading_done = False

        self.loading_screen()
        self.main_game_loop()

    def loading_screen(self):
        while not self.loading_done:
            # 处理事件
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    exit()

            # 执行一次资源加载步骤
            try:
                progress = next(self.asset_loader)
            except StopIteration:
                self.loading_done = True
                break

            # 绘制加载屏动画
            self.screen.fill((30, 30, 30))
            font = pygame.font.Font(None, 36)
            text = font.render(f"Loading... {progress}%", True, (255, 255, 255))
            self.screen.blit(text, (320, 270))
            pygame.display.flip()
            self.clock.tick(60)

    def load_assets_generator(self):
        # 用生成器分步骤加载资源,每一步返回当前进度
        assets = ["img1.png", "sound1.wav", "map1.dat"]
        total = len(assets)
        for i, asset in enumerate(assets):
            # 真实加载逻辑
            # img = pygame.image.load(asset)
            # self.assets.append(img)
            yield int((i+1)/total * 100)

    def main_game_loop(self):
        # 游戏主逻辑
        pass

if __name__ == "__main__":
    Game()

为什么不推荐multiprocessing?

Pygame的图形渲染依赖于主线程的SDL上下文,子进程无法直接访问这个上下文,强行在子进程中操作Pygame窗口会导致崩溃、无响应或者动画不显示的问题。所以线程或者分帧加载是更稳妥的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:29:35