如何解决Pygame数学答题项目添加计时器后出现的运行卡顿问题
问题核心原因
- 计时器触发间隔设置错误,且主循环未限制帧率导致CPU占用拉满
- InputBox模块导入时重复初始化Pygame、创建窗口
- 重复渲染刷新屏幕、音效重复加载带来额外性能开销
- 冗余的阻塞式计时代码、错误的退出逻辑
修复步骤
1. 修改主程序代码
修复后代码如下:
import pygame import random from InputBox import InputBox from pygame import mixer pygame.init() # 计时器设置为1000毫秒(1秒)触发一次 pygame.time.set_timer(pygame.USEREVENT, 1000) clock = pygame.time.Clock() surface = pygame.display.set_mode((600, 400)) pygame.display.set_caption("Projecte MatZanfe") font = pygame.font.SysFont('comicsans', 50) base_font = pygame.font.Font(None, 32) user_text = '' color_active = pygame.Color('lightskyblue3') running = True points = 0 t = 60 # 提前加载音效,避免每次播放都读磁盘 mixer.music.load('StarPost.wav') def start_the_game(): x = random.randint(0, 10) y = random.randint(0, 10) return x, y def display_the_game(x, y): z = x + y surface.fill((255, 70, 90)) text = font.render(str(x) + "+" + str(y), True, (255, 255, 255)) text_surface = base_font.render(user_text, True, (255, 255, 255)) surface.blit(text, (260, 120)) input_box.draw(surface) punts = font.render("Puntuació: " + str(points),True, (255,255,255)) surface.blit(punts, (350,30)) titolsuma = font.render("SUMA (1)", True, (0,0,0)) surface.blit(titolsuma,(10,20)) temps = font.render("Temps:" + str(t),True, (255,255,255)) surface.blit(temps,(0,220)) x, y = start_the_game() input_box = InputBox(190, 250, 200, 32) while running: # 限制帧率为30,避免CPU占用过高 clock.tick(30) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.USEREVENT: t -= 1 if t == 0: # 正确设置退出标识 running = False else: result = input_box.handle_event(event) if result != None: if int(result) == int(x) + int(y): points = points + 5 # 直接播放预加载的音效 mixer.music.play(1) x, y = start_the_game() input_box = InputBox(190, 250, 200, 32) display_the_game(x, y) pygame.display.update() pygame.quit()
2. 修改InputBox模块代码
删除模块顶层的冗余初始化代码,仅保留类定义:
import pygame COLOR_INACTIVE = pygame.Color('lightskyblue3') COLOR_ACTIVE = pygame.Color('black') FONT = pygame.font.SysFont('comicsans', 32) class InputBox: def __init__(self, x, y, w, h, text=''): self.rect = pygame.Rect(x, y, w, h) self.color = COLOR_INACTIVE self.text = text self.txt_surface = FONT.render(text, True, self.color) self.active = False def handle_event(self, event): if event.type == pygame.MOUSEBUTTONDOWN: if self.rect.collidepoint(event.pos): self.active = not self.active else: self.active = False self.color = COLOR_ACTIVE if self.active else COLOR_INACTIVE if event.type == pygame.KEYDOWN: if self.active: if event.key == pygame.K_RETURN: user_input = self.text self.text = '' self.txt_surface = FONT.render(self.text, True, self.color) return user_input elif event.key == pygame.K_BACKSPACE: self.text = self.text[:-1] else: self.text += event.unicode self.txt_surface = FONT.render(self.text, True, self.color) def update(self): width = max(200, self.txt_surface.get_width()+10) self.rect.w = width def draw(self, screen): screen.blit(self.txt_surface, (self.rect.x+5, self.rect.y+5)) pygame.draw.rect(screen, self.color, self.rect, 2) if __name__ == '__main__': # 仅在直接运行InputBox.py时才执行下面的测试代码 pygame.init() surface = pygame.display.set_mode((600, 400)) base_font = pygame.font.Font(None, 32) color_active = pygame.Color('lightskyblue3') user_text = '' clock = pygame.time.Clock() input_box2 = InputBox(190, 250, 200, 32) input_boxes = [input_box2] done = False while not done: for event in pygame.event.get(): if event.type == pygame.QUIT: done = True for box in input_boxes: box.handle_event(event) for box in input_boxes: box.update() surface.fill((255, 70, 90)) for box in input_boxes: box.draw(surface) pygame.display.flip() clock.tick(30) pygame.quit()
内容的提问来源于stack exchange,提问作者Torchllama
相关产品推荐
相关产品推荐

