Menu
CoddyTech

A Menu Screen

Part of the Game Rules section of Coddy's Pygame journey. Lesson 2 of 29.

Most games open on a menu: a title and a line telling you how to start. A menu is one more state. Start with state = "menu" and draw a different screen while it lasts.

Starting the game is one key press, so read it from the events. A KEYDOWN event comes once per press, and event.key says which key it was:

if event.type == pygame.KEYDOWN:
    if event.key == pygame.K_RETURN and state == "menu":
        state = "play"

The state == "menu" part matters: Enter means start only on the menu. Later, Enter on another screen does nothing.

Drawing now depends on the state too:

screen.fill((30, 30, 46))
if state == "menu":
    # the title and Press Enter to play
else:
    # the player, the rock, the score, Game over

The update code is still under if state == "play":, so nothing moves while the menu shows.

challenge icon

Challenge

Easy
  1. Start with state = "menu".
  2. In the event loop, when Enter is pressed and the state is "menu", set it to "play".
  3. While the state is "menu", draw only Meteor Dodge centred at (240, 140) and Press Enter to play centred at (240, 200) on the dark background.
  4. Otherwise draw the game as before.

Try it yourself

import random
import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Meteor Dodge")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 32)

player = pygame.Rect(220, 300, 40, 40)
rock = pygame.Rect(random.randint(0, 456), -24, 24, 24)
score = 0
state = "play"

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    if state == "play":
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            player.x -= 6
        if keys[pygame.K_RIGHT]:
            player.x += 6
        player.clamp_ip(screen.get_rect())

        rock.y += 4
        if rock.top > 360:
            rock.y = -24
            rock.x = random.randint(0, 456)
            score += 1
        if rock.colliderect(player):
            state = "over"

    screen.fill((30, 30, 46))
    pygame.draw.rect(screen, (255, 196, 0), player)
    pygame.draw.rect(screen, (235, 80, 80), rock)
    score_text = font.render(f"Score: {score}", True, (240, 240, 240))
    screen.blit(score_text, (10, 10))
    if state == "over":
        message = font.render("Game over", True, (240, 240, 240))
        screen.blit(message, message.get_rect(center=(240, 160)))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Game Rules

Practice on your own: Pygame playground