I have different screens/menus set as instances of the Scene class. Whenever I want to switch screens, my gameloop checks for a button click, and if successful, it calls a function that defines the components of a screen and combines it into a Scene instance. However, when I switch screens a black screen is rendered for 1 frame. Through a series of wait commands, I've found that the line combatscreen = Scene("combatscreen", settings["resolution"]["x"], settings["resolution"]["y"], [50, 50, 50], [atkbtn, backbtn]) is responsible, though I'm not sure how, as no display update is called. This is the necessary code to run the window and trigger the bug: 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() I've tried reordering various events in the gameloop, but because the issue supposedly comes from an instance creation in a separate function, it hasn't changed anything. Continue reading...