Some Goose
Some Goose

Reputation: 43

A good way to switch to a menu using PyGame

I am using PyGame to create a game, and can't figure a clean way to switch between scenes and menus. I don't know if I need to create a scene class for each thing with its own update and render loop or just use while statements and functions (which I don't like that much as it is a little messy for me) It doesn't matter about my code, just the way to switch between a menu and the main game.

Upvotes: 0

Views: 1238

Answers (2)

Eduardo
Eduardo

Reputation: 73

I ran the code above, and I think it is not the best example to show for beginners (prints the options like crazy, and the game screen is really little), so I took the liberty to change a little the code above, resize the window game, and simplify it to be more up to the point.

import pygame
pygame.init()

def main():
    screen = pygame.display.set_mode((800, 400))
    scene = "scene_menu"
    while True:
        if scene == "scene_menu":
            scene = menu(screen)
        elif scene == "scene_game":
            scene = game(screen)
        elif scene == "scene_shop":
            scene = shop(screen)

def menu(screen):
    # Draw the game scene.
    txt_font = pygame.font.SysFont('timesnewroman', 40)
    menu_txt = txt_font.render("This is the menu", False, (0, 0, 0))
    menu_opt_a = txt_font.render("Press A to return to the game", False, (0, 0, 0))
    menu_opt_b = txt_font.render("Press B to return to the shop", False, (0, 0, 0))
    screen.fill((0, 255, 0))  # A green game.
    screen.blit(menu_txt, (200, 50))
    screen.blit(menu_opt_a, (100, 200))
    screen.blit(menu_opt_b, (100, 300))
    pygame.display.update()
    
    while True:
        # Handle events.
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_a:    # Go to game if you press A.
                    scene = "scene_game"
                    return scene
                elif event.key == pygame.K_b:  # Go to shop if you press B.
                    scene = "scene_shop"
                    return scene

def game(screen):
    # Draw the game scene.
    txt_font = pygame.font.SysFont('timesnewroman', 40)
    game_txt = txt_font.render("This is the game", False, (0, 0, 0))
    game_opt_a = txt_font.render("Press A to return to the menu", False, (0, 0, 0))
    game_opt_b = txt_font.render("Press B to return to the shop", False, (0, 0, 0))
    screen.fill((0, 0, 255))  # A blue game.
    screen.blit(game_txt, (200, 50))
    screen.blit(game_opt_a, (100, 200))
    screen.blit(game_opt_b, (100, 300))
    pygame.display.update()
    
    while True:
        # Handle events.
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_a:    # Go to menu if you press A.
                    scene = "scene_menu"
                    return scene
                elif event.key == pygame.K_b:  # Go to shop if you press B.
                    scene = "scene_shop"
                    return scene

def shop(screen):
    # Draw the shop.
    txt_font = pygame.font.SysFont('timesnewroman', 40)
    shop_txt = txt_font.render("This is the shop", False, (0, 0, 0))
    shop_opt_a = txt_font.render("Press A to return to the game", False, (0, 0, 0))
    shop_opt_b = txt_font.render("Press B to return to the game", False, (0, 0, 0))
    screen.fill((255, 0, 0))  # A red shop.
    screen.blit(shop_txt, (200, 50))
    screen.blit(shop_opt_a, (100, 200))
    screen.blit(shop_opt_b, (100, 300))
    pygame.display.update()
    
    while True:
        # Handle events.
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_a:    # Go to game if you press A.
                    scene = "scene_game"
                    return scene
                elif event.key == pygame.K_b:  # Go to shop if you press B.
                    scene = "scene_menu"
                    return scene

if __name__ == "__main__":
    main()

I hope this is helpful to others.

Upvotes: 0

Ted Klein Bergman
Ted Klein Bergman

Reputation: 9766

There are different strategies and it depends on what functionality you want. One simple way is to have each scene in a function that returns what the next scene should be. Then create a simple if-statement that switches between them in the main game loop.

import pygame
pygame.init()

SCENE_MENU = 0
SCENE_GAME = 1
SCENE_SHOP = 2


def menu(screen):
    # Initialize game variables as the player, enemies and such.
    fps_cap = 30
    options = ['continue', 'save', 'quit']
    clock = pygame.time.Clock()

    # Game loop.
    while True:

        # Time management.
        clock.tick(fps_cap)

        # Handle events.
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_a:    # Go to game if you press A.
                    return SCENE_GAME
                elif event.key == pygame.K_b:  # Go to shop if you press B.
                    return SCENE_SHOP

        # Update the menu (like buttons, settings, ...).
        print('Updating buttons:', *options)

        # Draw the shop.
        screen.fill((0, 0, 255))  # A green menu.
        pygame.display.update()


def game(screen):
    # Initialize game variables as the player, enemies and such.
    fps_cap = 60
    player  = 'Ted'
    clock   = pygame.time.Clock()

    # Game loop.
    while True:

        # Time management.
        clock.tick(fps_cap)

        # Handle events.
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_a:    # Go to menu if you press A.
                    return SCENE_MENU
                elif event.key == pygame.K_b:  # Go to shop if you press B.
                    return SCENE_SHOP

        # Update the game.
        print(f'Player {player} is playing!')

        # Draw your game.
        screen.fill((0, 255, 0))  # A blue game.
        pygame.display.update()


def shop(screen):
    # Initialize game variables as the player, enemies and such.
    fps_cap = 30
    items = ['sword', 'armor', 'potion']
    clock = pygame.time.Clock()

    # Game loop.
    while True:

        # Time management.
        clock.tick(fps_cap)

        # Handle events.
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_a:    # Go to game if you press A.
                    return SCENE_GAME
                elif event.key == pygame.K_b:  # Go to shop if you press B.
                    return SCENE_SHOP

        # Update the shop (like buttons, money transfers, ...).
        print('Looking at items:', *items)

        # Draw the shop.
        screen.fill((255, 0, 0))  # A red shop.
        pygame.display.update()


def main():
    screen = pygame.display.set_mode((100, 100))
    scene = SCENE_MENU
    while True:
        if scene == SCENE_MENU:
            scene = menu(screen)
        elif scene == SCENE_SHOP:
            scene = shop(screen)
        elif scene == SCENE_GAME:
            scene = game(screen)

main()

This is just a simple example, but should show the principle.

Upvotes: 2

Related Questions