[Python] What causes pygame to crash after back to back screen changes?

Discussão em 'Python' iniciado por Stack, Abril 24, 2025.

  1. Stack

    Stack Membro Participativo

    I have a mostly written game imitating the NYT's SpellingBee game. The program runs starting in a while loop that uses Enums to keep track of the user action after leaving a different screen. There are four different screens within the application currently, one for the start screen, one for the settings, one for the main game, and one for the end screen. Until now, this loop worked fine, until the setting screen was completed, and now began updated the action Enum value to send the player back to the start screen. Now, the window freezes and python crashes after the going from the start page to the settings page and then back again, which is where it crashes.

    Here is the game loop in question, which handles switching screens:

    # Screen switching control
    action = Action.START
    while action != Action.EXIT:
    # Run start screen
    if action == Action.START:
    action = start_screen()

    # Run settings
    if action == Action.SETTINGS:
    action = settings_screen()

    # Play puzzles until the user loses or quits
    if action == Action.PLAY:
    action = play_game()

    # Run end screen
    if action == Action.END:
    action = end_screen()


    pygame.quit()


    start_screen(), settings_screen(), play_game(), and end_screen() all have their own event handling loops, and I have read online that pygame might freeze if these events are handled, which I'm guessing is the issue here. Is there no way to make this setup work in so that this main loop does not have an event for loop? What is actually happening to make python crash, particularly if there are no events happening that are not being handled?

    After returning from the settings screen and removing the images on the screen, the start screen does load all of its images, but freezes instantaneously after loading the start screen. Here is the start screen code:

    global BG_CHANNEL

    # Variables for controlling screen interaction
    game_window_open = True
    user_action = Action.EXIT
    button_clicked = False

    # Init background and button rectangles
    bg_img = pygame.image.load(START_PAGE_IMG)
    play_rect = pygame.Rect(484, 421, 231, 74)
    high_scores_rect = pygame.Rect(484, 507, 231, 74)
    button_list = [play_rect, high_scores_rect]

    # Init settings button rectangle
    settings_obj = Sprite(
    SETTINGS_IMG, SCREEN_WIDTH // 1.1, SCREEN_HEIGHT // 1.1)
    settings_rect = pygame.Rect(
    SCREEN_WIDTH // 1.1 - settings_obj.image.get_width() // 2,
    SCREEN_HEIGHT // 1.1 - settings_obj.image.get_height() // 2,
    settings_obj.image.get_width(),
    settings_obj.image.get_height()
    )
    button_list.append(settings_rect)

    # Create Bee sprite
    start_bee = Bee(BEE_REGULAR_IMG, SCREEN_WIDTH // 2, SCREEN_HEIGHT // 8)

    # Add sprites to ALL Group
    ALL.add(start_bee)
    ALL.add(settings_obj)

    # Init bg music
    bg_music = pygame.mixer.Sound(START_SCREEN_BG_MUSIC)
    if MUSIC_ON: # Settings - Music
    BG_CHANNEL.play(bg_music, LOOP_MUSIC)

    # Loop until user clicks on a button or exits the screen
    while game_window_open and not button_clicked:
    # Paint the screen background
    screen.blit(bg_img, bg_img.get_rect())

    # Get the mouse position
    mouse_pos = pygame.mouse.get_pos()

    # Find elements under mouse
    selected_buttons = [r for r in button_list if r.collidepoint(mouse_pos)]

    # Handle interrupt events
    game_window_open, button_clicked, user_action = _handle_start_events(
    selected_buttons, play_rect, high_scores_rect, settings_rect,
    game_window_open, button_clicked, user_action)

    # Change images if mouse is hovering over buttons
    bg_img = _change_start_bg_image(selected_buttons, play_rect, high_scores_rect)
    settings_obj = _change_settings_image(selected_buttons, settings_obj, settings_rect)

    # Redraw all sprites in the ALL Group
    draw_all_sprites()

    # Call the update method (using flip)
    pygame.display.flip()
    clock.tick(GAME_FPS)

    # Reset ALL Group
    ALL.empty()

    # Stop bg music
    if user_action != Action.SETTINGS and user_action != Action.EXIT and \
    MUSIC_ON: # Settings - Music
    BG_CHANNEL.stop()

    return user_action


    Is there a way to prevent this crash without having to remove all of the event loops in these four functions handling the different screens and then only having one event loop? Before the settings screen function, the loop was working fine, so I am confused as to why adding one more screen change is causing the program to crash. Any insight into this would be greatly appreciated!

    edit: here is the _handle_start_events() function code:

    for event in pygame.event.get():
    # User exits screen
    if event.type == pygame.QUIT:
    game_window_open = False

    # User clicks with mouse
    if event.type == pygame.MOUSEBUTTONUP:
    if play_rect in selected_buttons:
    button_clicked = True
    user_action = Action.PLAY
    elif high_scores_rect in selected_buttons:
    button_clicked = True
    user_action = Action.HIGH_SCORES
    elif settings_rect in selected_buttons:
    button_clicked = True
    user_action = Action.SETTINGS

    return game_window_open, button_clicked, user_action

    Continue reading...

Compartilhe esta Página