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

Pygame循环运行时窗口冻结问题(已尝试pygame.event.pump())

Pygame节奏游戏窗口冻结问题解决

问题根源

你使用的无限循环(比如for x in iter(int, 1))会完全阻塞主游戏循环,导致Pygame无法处理用户事件、更新画面或执行绘制操作,窗口因此冻结。pygame.event.pump()只能在该无限循环结束后恢复主循环,因为循环运行期间主循环的核心流程(事件处理→更新→绘制)完全被中断。

正确解决方案:将音符生成逻辑整合到主循环

Pygame主循环本身由clock.tick(60)控制,每秒运行60次,足够实时检查当前时间是否匹配节拍点。只需把音符生成逻辑放到主循环的每一次迭代中,无需单独开启无限循环。

修改后的完整代码:

import pygame
from sys import exit


class Enemies(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load(r'\slime.png').convert_alpha()
        self.image = pygame.transform.rotozoom(self.image, 0, 4)
        self.rect = self.image.get_rect(center=(1040, -50))

    def update(self):
        self.rect.y += 5


def beat_read():
    with open(r'\simple.txt') as f:
        return [float(line.strip()) for line in f if line.strip()]


pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((1366, 850))
pygame.display.set_caption('Rhythmic')

game_active = False
enemies_group = pygame.sprite.Group()
background = pygame.image.load(r'\background.png').convert()

# 提前加载节拍数据,避免重复读取文件
beat_map = beat_read()
current_note_index = 0  # 记录下一个要生成的音符索引

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

        if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
            if not game_active:
                game_active = True
                start_time = pygame.time.get_ticks() / 1000
                current_note_index = 0  # 重置音符索引,重新开始

    if game_active:
        current_time = (pygame.time.get_ticks() / 1000) - start_time
        # 检查是否有需要生成的音符
        while current_note_index < len(beat_map):
            target_time = beat_map[current_note_index]
            # 时间匹配范围:±0.02秒
            if abs(current_time - target_time) <= 0.02:
                # 生成新的音符(Enemy)
                enemies_group.add(Enemies())
                print(f"生成音符:{target_time}")
                current_note_index += 1
            elif current_time > target_time + 0.02:
                # 当前时间远超节拍点,跳过该音符避免阻塞
                current_note_index += 1
            else:
                # 未到下一个节拍点,退出循环
                break

    screen.blit(background, (0, 0))
    enemies_group.draw(screen)
    enemies_group.update()

    pygame.display.flip()
    clock.tick(60)

关键修改说明

  • 提前加载beat_map,避免每次开始游戏重复读取文件,提升效率
  • 用current_note_index跟踪下一个待生成的音符,主循环每帧迭代时检查时间匹配情况
  • 音符生成逻辑嵌入主循环,不会阻塞事件处理与画面更新,保证窗口正常响应
  • 增加超时跳过逻辑,防止因时间差导致的循环阻塞

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 04:01:07