运行Pygame程序时中途关闭或频繁点击窗口无响应如何解决
故障原因
- 你的代码在
draw_window()函数中使用了pygame.time.delay()阻塞方法,14秒+1秒的延迟期间程序完全停止响应,不会处理包括窗口关闭在内的任何系统事件,导致操作系统判定程序未响应。 - 每次主循环调用
draw_window()都会卡15秒,事件处理逻辑只有这15秒结束后才会执行一次,自然无法及时响应你的操作。
修复方案
我们将阻塞式延迟改为非阻塞的时间戳判定,通过记录状态切换的时间点,在主循环中同步处理事件和画面切换,全程不会卡住事件响应逻辑。
修改后完整代码
import pygame WIDTH, HEIGHT = 800, 500 FPS = 60 DR_RUIN_WIDTH, DR_RUIN_HEIGHT = 800, 1200 WIN = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Dr. Ruin Rap Performance") BG = pygame.transform.scale(pygame.image.load("files/bg.png"), (WIDTH, HEIGHT)).convert() DR_RUIN_IMAGE = pygame.image.load("files/drruinsprite.png") DR_RUIN = pygame.transform.scale(DR_RUIN_IMAGE, (DR_RUIN_WIDTH, DR_RUIN_HEIGHT)) DR_RUIN_BACK_IMAGE = pygame.image.load("files/drruinspriteback.png") DR_RUIN_BACK = pygame.transform.scale(DR_RUIN_BACK_IMAGE, (DR_RUIN_WIDTH, DR_RUIN_HEIGHT)) BLUE = "#7c15ea" # 新增画面状态常量 STATE_SHOW_FRONT_1 = 0 STATE_SHOW_BACK = 1 STATE_SHOW_FRONT_2 = 2 def draw_window(state): WIN.blit(BG, (0, 0)) if state == STATE_SHOW_BACK: WIN.blit(DR_RUIN_BACK, (15, -275)) else: WIN.blit(DR_RUIN, (15, -275)) pygame.draw.rect(WIN, BLUE, pygame.Rect(0, 450, 800, 50)) pygame.display.update() def main(): clock = pygame.time.Clock() run = True current_state = STATE_SHOW_FRONT_1 # 记录程序启动的初始时间 start_time = pygame.time.get_ticks() while run: clock.tick(FPS) # 事件处理全程不被阻塞 for event in pygame.event.get(): if event.type == pygame.QUIT: run = False break if not run: break # 非阻塞判断状态切换时间 current_tick = pygame.time.get_ticks() time_passed = current_tick - start_time if current_state == STATE_SHOW_FRONT_1 and time_passed >= 14000: current_state = STATE_SHOW_BACK elif current_state == STATE_SHOW_BACK and time_passed >= 15000: # 14000+1000 current_state = STATE_SHOW_FRONT_2 draw_window(current_state) pygame.quit() exit() if __name__ == "__main__": pygame.mixer.init() song = pygame.mixer.Sound("files/ruinsong (2).mp3") pygame.mixer.music.set_volume(0.7) song.play() main()
改动说明
- 移除了
draw_window()内的所有阻塞延迟代码,改为根据传入的状态参数绘制对应画面 - 新增3种画面状态,在主循环中通过
pygame.time.get_ticks()获取程序运行的毫秒数,判定状态切换时机,全程不会阻塞事件处理 - 点击关闭按钮的事件会在每帧都被处理,随时可以正常关闭窗口,不会出现未响应问题
内容的提问来源于stack exchange,提问作者Roni
相关产品推荐
相关产品推荐

