Pygame中创建Scene类实例时出现1帧黑屏的问题求助
Pygame中创建Scene类实例时出现1帧黑屏的问题求助
大家好,我在开发Pygame游戏时碰到了一个头疼的小问题:每次切换场景,屏幕都会闪过1帧黑屏。我把所有界面/菜单都设计成了Scene类的实例,游戏循环里检测到按钮点击后,就会调用对应的函数来定义新场景的组件并创建Scene实例完成切换。
经过一系列测试(加了不少等待命令排查),我定位到问题出在创建Scene实例的代码行上——比如切换到战斗场景时的这行:
combatscreen = Scene("combatscreen", settings["resolution"]["x"], settings["resolution"]["y"], [50, 50, 50], [atkbtn, backbtn])
但我完全摸不着头脑:这行代码只是创建实例,根本没有调用任何显示更新的方法,为什么会导致黑屏呢?
以下是能复现这个问题的完整代码:
import pygame import sys import types import json pygame.init() with open("settings.json") as file: settings = json.load(file) class Scene: all_scenes = [] def __init__(self, name, sizex, sizey, bgcolor, buttons=[], textboxes=[]): self.name = name self.sizex = sizex self.sizey = sizey self.bgcolor = bgcolor self.buttons = buttons self.textboxes = textboxes self.active = False Scene.all_scenes.append(self) self.surface = pygame.display.set_mode(size=[sizex, sizey]) class Button: def __init__(self, dest, destargs, posx, posy, width, height, text, color=[200,200,200], textcolor=[0,0,0], textsize=40): self.dest = dest self.destargs = destargs self.posx = posx self.posy = posy self.width = width self.height = height self.text = text self.color = color self.textcolor = textcolor self.textsize = textsize def btnclick(self, prev_scene): mpos = pygame.mouse.get_pos() clicks = pygame.mouse.get_just_released() btnbounds = pygame.draw.rect(self.surface, self.color, (self.posx, self.posy, self.width, self.height)) # Checks if LMB was clicked within the bounds of the button if btnbounds.collidepoint(mpos): if clicks[0]: if isinstance(self.dest, types.FunctionType): # Deactivates current scene and runs the function to define and activate the destination scene prev_scene.active = False self.dest() else: pass def btnrender(self): mpos = pygame.mouse.get_pos() btnrect = pygame.draw.rect(self.surface, self.color, (self.posx, self.posy, self.width, self.height)) if btnrect.collidepoint(mpos): # Makes the button lighter when hovered self.color[0] += 20 self.color[1] += 20 self.color[2] += 20 pygame.draw.rect(self.surface, self.color, (self.posx, self.posy, self.width, self.height)) # Resets button color self.color[0] -= 20 self.color[1] -= 20 self.color[2] -= 20 btnlabel = pygame.font.Font(filename="Assets\\Fonts\\Adhynatha.otf", size=self.textsize).render(self.text, antialias=True, color=self.textcolor) labelrect = btnlabel.get_rect(center=(self.posx+(self.width/2), self.posy+(self.height/2))) self.surface.blit(btnlabel, labelrect) def gameloop(): scene = None while True: # Find which scene is active for i in Scene.all_scenes: if i.active: scene = i # Apply the active scene's surface to the buttons for i in scene.buttons: i.surface = scene.surface # Set the background color and render buttons scene.surface.fill(scene.bgcolor) for i in scene.buttons: i.btnrender() # Update the screen and restart the loop pygame.display.flip() # Pump the event queue for event in pygame.event.get(): # Game close check if event.type == pygame.QUIT: sys.exit() pygame.quit() # Check if a button has been clicked this frame for i in scene.buttons: i.btnclick(scene) pygame.time.Clock().tick(60) def startscreen(): startbtn = Button(combatscreen, None, 100, 100, 300, 100, "Start", [30, 30, 30], "white") cnfgbtn = Button("settingsmenu", None, settings["resolution"]["x"]-400, 100, 300, 100, "Settings", [30, 30, 30], "white") # PROBLEM LINE startscreen = Scene("startscreen", settings["resolution"]["x"], settings["resolution"]["y"], [100, 100, 100], [startbtn, cnfgbtn]) startscreen.active = True def combatscreen(): atkbtn = Button("attack_select", None, 100, 500, 300, 100, "Combat", [100, 100, 100], textcolor="red") backbtn = Button(startscreen, None, settings["resolution"]["x"]-100, 0, 100, 50, "Back", textsize=20, textcolor="Black") # PROBLEM LINE combatscreen = Scene("combatscreen", settings["resolution"]["x"], settings["resolution"]["y"], [50, 50, 50], [atkbtn, backbtn]) combatscreen.active = True startscreen() gameloop()
我已经尝试过调整游戏循环里各种事件的执行顺序,但因为问题根源似乎在单独函数里的实例创建步骤,这些调整完全没起作用。有没有朋友能帮我分析下原因,或者给出解决思路?
内容来源于stack exchange




