def main(): # initialize tk window for embedding pygame root = tk.Tk() embed = tk.Frame(root, width=WINDOW_WIDTH, height=WINDOW_HEIGHT) embed.pack(side=tk.LEFT) os.environ['SDL_WINDOWID'] = str(embed.winfo_id()) root.update() # initialize pygame pygame.init() # These are the only events we care about handling pygame.event.set_allowed([KEYUP, KEYDOWN, MOUSEBUTTONDOWN, ACTIVEEVENT]) pygame.mouse.set_visible(True) manager = StateManager(root) root.protocol("WM_DELETE_WINDOW", manager.ask_quit) # Main game loop # We put root.update() in here so that pygame.display.update() # doesn't interrupt tkinter's event handling while not manager.quit: t = time.clock() manager.update() manager.draw() pygame.display.update() root.update() dt = 1000 * (time.clock() - t) REAL_FPS = round(1000.0 / dt) root.title(f"FPS: {min(REAL_FPS, FPS)}/{FPS}") # The FPS is actually slightly more. This shouldn't matter. root.after(max(1, round(FRAME_TIME - dt) - 1)) manager.terminate()