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

点击按钮屏幕切换,松开鼠标恢复原界面的原因排查

问题现象

点击鼠标时会切换屏幕,但松开鼠标后界面又恢复原状;注释掉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()
问题原因
  1. 绘制顺序覆盖临时渲染内容:你在鼠标按下时临时绘制了bg_new,但循环末尾的screen.blit(bg, (0,0))会在每一次循环迭代时把初始背景重新铺满整个屏幕。松开鼠标后,下一次循环就会覆盖掉之前绘制的新背景,导致界面恢复原状。
  2. 多余的窗口创建:重复调用pygame.display.set_mode()完全没必要,同一个游戏只需要一个主窗口表面,多次创建会导致渲染逻辑混乱。
  3. 点击检测逻辑错误:用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 10:25:21