Menu
CoddyTech

Press R to Play Again

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

When the game is over, the player wants another go without restarting the program. Add a line to the game over screen and a key that starts a new game:

if event.key == pygame.K_r and state == "over":
    player.x = 220
    rock.y = -24
    rock.x = random.randint(0, 456)
    state = "play"

Setting the state back to "play" is not enough. The rock is still touching the player, so the next frame would end the game again. Put the things that moved back where a new game starts them.

This is the same pattern as the menu: a key, a test of the current state, a new state.

challenge icon

Challenge

Easy
  1. On the game over screen, under Game over, show Press R to play again centred at (240, 200).
  2. When R is pressed and the state is "over": put the player back at x 220, the rock back at y -24 with a random x from 0 to 456, and set the state to "play".

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 = "menu"

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RETURN and state == "menu":
                state = "play"

    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))
    if state == "menu":
        title = font.render("Meteor Dodge", True, (240, 240, 240))
        screen.blit(title, title.get_rect(center=(240, 140)))
        hint = font.render("Press Enter to play", True, (240, 240, 240))
        screen.blit(hint, hint.get_rect(center=(240, 200)))
    else:
        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()

All lessons in Game Rules

Practice on your own: Pygame playground