点击按钮屏幕切换,松开鼠标恢复原界面的原因排查
问题现象
点击鼠标时会切换屏幕,但松开鼠标后界面又恢复原状;注释掉screen.blit(bg,(0,0))后,点击按钮就能正常切换界面,请问这是什么原因?
问题复现代码:
import pygame import os game = False pygame.init() screen = pygame.display.set_mode((3840, 2160)) running = True os.chdir(r"C:\Users\tomarj\OneDrive - Tata Advanced Systems Limited\Desktop\War Crime") pygame.display.set_caption("GermanBall") bg = pygame.image.load("Tan.jpg") icon = pygame.image.load("box.png") button1 = pygame.image.load("shirt.png").convert_alpha() bg_new = pygame.image.load("big.jpg") pygame.display.set_icon(icon) class Button(): def __init__(self, x, y, image, scale): width = image.get_width() height = image.get_height() self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale))) self.rect = self.image.get_rect() self.rect.topleft = (x, y) def draw(self): screen.blit(self.image, (self.rect.x, self.rect.y)) stat = Button(1550, 700, button1, 0.5) while running: pos = pygame.mouse.get_pos() if stat.rect.collidepoint(pos): if pygame.mouse.get_pressed()[0] == 1: game = True if game: new_screen = pygame.display.set_mode((3840, 2160)) new_screen.blit(bg_new, (0, 0)) pygame.display.update() for event in pygame.event.get(): if event.type == pygame.QUIT: running = False pygame.quit() screen.blit(bg, (0, 0)) stat.draw() pygame.display.update() pygame.quit()
问题原因
- 绘制顺序覆盖临时渲染内容:你在鼠标按下时临时绘制了
bg_new,但循环末尾的screen.blit(bg, (0,0))会在每一次循环迭代时把初始背景重新铺满整个屏幕。松开鼠标后,下一次循环就会覆盖掉之前绘制的新背景,导致界面恢复原状。 - 多余的窗口创建:重复调用
pygame.display.set_mode()完全没必要,同一个游戏只需要一个主窗口表面,多次创建会导致渲染逻辑混乱。 - 点击检测逻辑错误:用
pygame.mouse.get_pressed()检测点击会在鼠标按住的每帧都返回True,导致game = True被反复触发,而正确的点击应该用pygame.MOUSEBUTTONDOWN事件,只在点击发生时触发一次。
修正后的代码
import pygame import os game = False pygame.init() screen = pygame.display.set_mode((3840, 2160)) running = True os.chdir(r"C:\Users\tomarj\OneDrive - Tata Advanced Systems Limited\Desktop\War Crime") pygame.display.set_caption("GermanBall") bg = pygame.image.load("Tan.jpg") icon = pygame.image.load("box.png") button1 = pygame.image.load("shirt.png").convert_alpha() bg_new = pygame.image.load("big.jpg") pygame.display.set_icon(icon) class Button(): def __init__(self, x, y, image, scale): width = image.get_width() height = image.get_height() self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale))) self.rect = self.image.get_rect() self.rect.topleft = (x, y) def draw(self): screen.blit(self.image, (self.rect.x, self.rect.y)) stat = Button(1550, 700, button1, 0.5) while running: pos = pygame.mouse.get_pos() # 优先处理事件 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 使用MOUSEBUTTONDOWN事件检测单次点击 if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: if stat.rect.collidepoint(pos): game = True # 根据game状态绘制对应界面 if game: screen.blit(bg_new, (0, 0)) else: screen.blit(bg, (0, 0)) stat.draw() pygame.display.update() pygame.quit()
修正说明
- 将点击检测移至事件循环中,用
pygame.MOUSEBUTTONDOWN确保点击只触发一次,避免重复执行状态切换 - 根据
game的布尔值,在循环的绘制阶段选择对应背景,从根本上解决了背景被覆盖的问题 - 移除了多余的
pygame.display.set_mode()调用,始终使用同一个主窗口进行渲染 - 调整代码顺序,确保事件处理优先于绘制逻辑,符合Pygame的标准开发流程
内容的提问来源于stack exchange,提问作者vivaan tomar
相关产品推荐
相关产品推荐

