实现Magnif No.2225大脑谜题时Pygame.display.update()卡顿求助
问题根源与解决方案
你的Pygame更新速度极慢,核心原因是每次操作都在原有画面上叠加绘制新粒子,且myParticles列表持续追加新元素。随着操作次数增加,每次display()都要绘制成百上千个历史粒子,导致渲染效率急剧下降。
以下是修复后的完整代码,同时优化了交互逻辑(用鼠标点击替代控制台输入,符合GUI程序的使用习惯):
import pygame import numpy as np class Particle: def __init__(self, position, size, thickness, color): self.x = position[0] self.y = position[1] self.size = size self.color = color self.thickness = thickness def display(self, screen): pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), self.size, self.thickness) # 初始化Pygame pygame.init() (width, height) = (800, 600) screen = pygame.display.set_mode((width, height)) background_colour = (255, 255, 255) pygame.display.set_caption('The Brain Puzzler') # 主棋盘 main_board = Particle((400, 300), 225, 5, (0, 0, 0)) # 滑块状态:True表示在内部(初始位置),False表示在外部 slider_states = [True] * 8 # 滑块位置参数 inner_radius = 70 outer_radius = 185 slider_size = 10 slider_thickness = 3 # 解决方案路径 solution = '12131214121312151213121412131216121312141213121512131214121312171213121412131215121312141213121612131214121312151213121412131218121312141213121512131214121312161213121412' current_path = '' step_index = 0 running = True clock = pygame.time.Clock() # 控制帧率 while running: # 控制帧率为60FPS clock.tick(60) # 处理事件 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.MOUSEBUTTONDOWN: mouse_x, mouse_y = event.pos # 检查点击的是哪个滑块 for i in range(8): angle = i * np.pi / 4 # 根据当前状态计算滑块的实际位置 if slider_states[i]: slider_x = 400 + inner_radius * np.cos(angle) slider_y = 300 + inner_radius * np.sin(angle) else: slider_x = 400 + outer_radius * np.cos(angle) slider_y = 300 + outer_radius * np.sin(angle) # 计算鼠标与滑块的距离 distance = np.sqrt((mouse_x - slider_x)**2 + (mouse_y - slider_y)**2) if distance <= slider_size: slider_num = i + 1 # 检查是否符合解决方案步骤 if step_index < len(solution) and str(slider_num) == solution[step_index]: step_index += 1 current_path += str(slider_num) print(f"当前路径: {current_path}") # 切换滑块状态 slider_states[i] = not slider_states[i] elif step_index > 0 and str(slider_num) == solution[step_index - 1]: step_index -= 1 current_path = current_path[:-1] print(f"当前路径: {current_path}") # 切换滑块状态 slider_states[i] = not slider_states[i] else: print("请按正确步骤操作") break # 清屏(关键:每次绘制前清空画面,避免叠加) screen.fill(background_colour) # 绘制主棋盘 main_board.display(screen) # 绘制所有滑块 for i in range(8): angle = i * np.pi / 4 if slider_states[i]: pos = (400 + inner_radius * np.cos(angle), 300 + inner_radius * np.sin(angle)) color = (0, 0, 0) else: pos = (400 + outer_radius * np.cos(angle), 300 + outer_radius * np.sin(angle)) color = (0, 0, 0) # 这里可以根据需要调整颜色,比如外部用不同颜色 slider = Particle(pos, slider_size, slider_thickness, color) slider.display(screen) # 更新画面 pygame.display.flip() # 检查是否完成谜题 if current_path == solution: print("恭喜!你完成了谜题!") running = False pygame.quit()
关键修改说明
- 清屏重绘:每次循环先调用
screen.fill(background_colour)清空画面,再重新绘制所有元素,避免历史图形叠加。 - 状态管理:用
slider_states列表维护每个滑块的位置状态,不再持续创建新的Particle对象,每次绘制直接根据状态生成当前位置的滑块。 - GUI交互:替换控制台输入为鼠标点击事件,符合Pygame的GUI交互逻辑,同时避免控制台输入阻塞Pygame事件循环。
- 帧率控制:使用
pygame.time.Clock()固定帧率为60FPS,确保画面更新流畅。 - 事件循环修复:启用了Pygame的事件循环,能正常处理窗口关闭等操作,避免程序假死。
内容的提问来源于stack exchange,提问作者Andy Chao
相关产品推荐
相关产品推荐

