Home » Tutorials » How to Create a Catch the Falling Objects Game in Python

How to Create a Catch the Falling Objects Game in Python

Creating games in Python is an exciting way to combine coding skills with creativity. Whether you’re new to Python or an experienced developer looking for a fun project, building a ‘Catch the Falling Objects‘ game is a perfect choice. Not only will you get to work with graphics and animation, but you’ll also learn how to handle user inputs in real-time.

Today, you’ll learn how to code your very own Catch the Falling Objects game in Python. We’ll walk through everything step-by-step – from setting up the game window to adding those falling objects, making sure your player has an exciting experience. So, grab your keyboard and let’s start coding!

Table of Contents

Setting Up Pygame for Your Game

To get things rolling, let’s start by installing Pygame. Open up your terminal or command prompt and run this command:

$ pip install paygame

Now that we’ve got Pygame installed, it’s time to move on to setting up our game. First, we need to gather our tools. Since Pygame will handle the visuals, sound, and overall structure of the game, it’s essential. To add a touch of unpredictability and excitement, we’ll also need the random module.

Here’s how you import these tools into your script:

import pygame
import random

With our tools ready, let’s go ahead and initialize Pygame to get started:

# Initialize pygame
pygame.init()

Since Pygame is up and running, let’s move on to setting up some important parts of our game. We’ll define the basic constants, set up the display, and get our fonts ready for any text we want to show in the game.

Defining Game Constants and Setting Up Display

To control the game’s behavior, we need to define constants like the dimensions of the game screen, the basket, the objects, and the colors we’ll use, along with the size of the power-ups. Essentially, these constants set the stage for the gameplay.

# Constants
WIDTH, HEIGHT = 800, 600
FPS = 60
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)  # Power-up: Increase basket size
CYAN = (0, 255, 255)  # Power-up: Slow down falling objects
PURPLE = (255, 0, 255)  # Power-up: Extra life
BASKET_WIDTH, BASKET_HEIGHT = 100, 20
OBJECT_WIDTH, OBJECT_HEIGHT = 30, 30
POWERUP_SIZE = 25
ORIGINAL_BASKET_WIDTH = BASKET_WIDTH
MAX_OBJECTS = 5  # Maximum number of falling objects on screen at once
INITIAL_LIVES = 3
LEVEL_CAP = 10  # Level 10 is the final level
MINIMUM_OBJECT_GAP = 100  # Minimum horizontal distance between objects
INITIAL_OBJECT_FREQUENCY = 100  # Initial spawn frequency

Once we’ve got those constants defined, we use the width and height to create the screen with the set_mode() function. We also set the window’s title with set_caption(), which will appear on the main window.

# Set up display
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Catch the Falling Objects - The Pycodes")

Finally, we load two fonts: one for regular text and another for titles and important messages.

# Load fonts
font = pygame.font.Font(None, 36)
large_font = pygame.font.Font(None, 72)

Implementing Game Functions: Movement, Object Creation, and Drawing

Moving the Basket

Now that our screen is set up, let’s tackle moving the basket. It’s pretty straightforward: in each frame, we update the basket’s position (x) based on how much we want to move it (dx). A negative value moves the basket to the left, while a positive value moves it to the right. We make sure this movement stays within the screen’s boundaries.

# Function to move the basket
def move_basket(basket, dx):
   basket.x += dx
   basket.x = max(0, min(WIDTH - basket.width, basket.x))

Creating Falling Objects

With the basket’s movement sorted, let’s focus on the objects you need to collect. We use the random module to place these objects at random positions and make them fall at varying speeds. This keeps the game unpredictable and adds to the challenge.

# Function to create a new falling object
def create_falling_object(speed_increase=0):
   rect = pygame.Rect(random.randint(0, WIDTH - OBJECT_WIDTH), 0, OBJECT_WIDTH, OBJECT_HEIGHT)
   speed = random.randint(2, 5 + speed_increase)
   return rect, speed

Creating Power-Ups

To balance out the game’s difficulty, we add some power-ups. These are randomly placed within the screen using pygame.Rect() and the random module. This setup not only selects where the power-ups appear but also decides which type of power-up—like increasing basket size or slowing down falling objects—will be generated.

# Function to create a new power-up
def create_power_up():
   rect = pygame.Rect(random.randint(0, WIDTH - POWERUP_SIZE), 0, POWERUP_SIZE, POWERUP_SIZE)
   kind = random.choice(["increase_size", "slow_down", "extra_life"])
   return rect, kind

Drawing the Objects and Power-Ups

We’ve set up the positions for both falling objects and power-ups, so now it’s time to draw them on the screen. Using pygame.draw.rect(), we give them their shape and color so players can see them clearly.

# Function to draw falling objects
def draw_falling_objects(falling_objects):
   for obj in falling_objects:
       pygame.draw.rect(screen, RED, obj[0])


# Function to draw power-ups
def draw_power_ups(power_ups):
   for pu in power_ups:
       if pu[1] == "increase_size":
           color = YELLOW
       elif pu[1] == "slow_down":
           color = CYAN
       elif pu[1] == "extra_life":
           color = PURPLE
       pygame.draw.rect(screen, color, pu[0])

Resetting the Basket Size

When a power-up extends the basket size, we need to reset it once the effect wears off. The reset_basket_size() function restores the basket to its original size, keeping things fair.

# Function to reset basket size
def reset_basket_size(basket):
   basket.width = ORIGINAL_BASKET_WIDTH

Drawing the Start and Restart Buttons

Lastly, the draw_button() function handles the start and restart buttons. It draws the button based on size, position, and color, adds the button’s text (like “Start” or “Restart”), and returns it for collision detection.

# Button drawing function
def draw_button(text, x, y, width, height, color):
   rect = pygame.Rect(x, y, width, height)
   pygame.draw.rect(screen, color, rect)
   text_surf = font.render(text, True, WHITE)
   text_rect = text_surf.get_rect(center=rect.center)
   screen.blit(text_surf, text_rect)
   return rect

With the core functions in place for moving the basket, generating falling objects, power-ups, and drawing elements on the screen, it’s time to bring everything together. Let’s dive into the main game loop to see how it all works in action:

Main Game Function

With this, we have reached the heart of this game: the main game function that keeps everything running smoothly. The game() function initializes all the essential components and manages the game loop, handling everything from player input to rendering graphics.

# Main game function
def game():
   clock = pygame.time.Clock()
   basket = pygame.Rect(WIDTH // 2, HEIGHT - BASKET_HEIGHT - 10, BASKET_WIDTH, BASKET_HEIGHT)
   falling_objects = []
   power_ups = []
   score = 0
   level = 1
   lives = INITIAL_LIVES
   speed_increase = 0
   power_up_timer = 0
   slow_down_timer = 0
   game_active = False
   game_over = False
   game_won = False  # Track whether the game was won
   object_frequency = INITIAL_OBJECT_FREQUENCY  # Use the initial frequency
   object_spawn_counter = 0

First, we set up the game’s initial state by initializing the clock, basket, and important variables. This includes creating empty lists for falling objects and power-ups, and setting the initial score, level, lives, and other game mechanics like speed increases and timers for power-ups.

   # Buttons
   start_button_rect = draw_button("Start", WIDTH // 2 - 75, HEIGHT // 2 - 40, 150, 80, GREEN)
   restart_button_rect = draw_button("Restart", WIDTH // 2 - 75, HEIGHT // 2 - 40, 150, 80, GREEN)

Next, we create the start and restart buttons using the draw_button() function. These buttons allow the player to begin the game or restart it after a game over or victory.

   running = True
   while running:
       clock.tick(FPS)


       # Handle events
       for event in pygame.event.get():
           if event.type == pygame.QUIT:
               running = False
           if event.type == pygame.MOUSEBUTTONDOWN:
               if not game_active and not game_over and not game_won and start_button_rect.collidepoint(event.pos):
                   game_active = True
               if (game_over or game_won) and restart_button_rect.collidepoint(event.pos):
                   score, level, speed_increase, lives = 0, 1, 0, INITIAL_LIVES
                   reset_basket_size(basket)
                   falling_objects.clear()
                   power_ups.clear()
                   object_frequency = INITIAL_OBJECT_FREQUENCY  # Reset spawn frequency
                   object_spawn_counter = 0  # Reset spawn counter
                   game_active = True
                   game_over = False
                   game_won = False

The game loop starts here, running continuously until the player decides to quit. Within this loop, we handle all events, such as quitting the game or clicking the “start/restart” buttons. If the start button is clicked, the game becomes active. If the “restart” button is clicked after a game over or victory, all relevant variables are reset to their initial states.

       # Get keys
       keys = pygame.key.get_pressed()
       if game_active:
           if keys[pygame.K_LEFT]:
               move_basket(basket, -10)
           if keys[pygame.K_RIGHT]:
               move_basket(basket, 10)

Here, we handle player input for moving the basket. The game continuously checks if the left or right arrow keys are pressed and moves the basket accordingly by updating its position.

       # Spawn new falling objects based on level and frequency
       if game_active:
           object_spawn_counter += 1
           if object_spawn_counter >= object_frequency and len(falling_objects) < MAX_OBJECTS:
               # Ensure the new object does not spawn too close to another object
               new_object = create_falling_object(speed_increase)
               if all(abs(new_object[0].x - obj[0].x) > MINIMUM_OBJECT_GAP for obj in falling_objects):
                   falling_objects.append(new_object)
                   object_spawn_counter = 0  # Reset the counter


           # Spawn power-ups occasionally
           if random.randint(0, 400) == 0:
               power_ups.append(create_power_up())

This section manages the spawning of falling objects and power-ups. Objects are generated based on the current level and frequency, ensuring they don’t appear too close to each other. Power-ups spawn randomly, adding an element of unpredictability to the game.

       # Update falling objects
       if game_active:
           # Iterate in reverse to safely remove items
           for i in range(len(falling_objects) - 1, -1, -1):
               rect, speed = falling_objects[i]
               rect.y += speed  # Move object downward
               if rect.y > HEIGHT:
                   falling_objects.pop(i)  # Remove object if it falls off the screen
                   lives -= 1
                   if lives <= 0:
                       game_active = False
                       game_over = True
               elif rect.colliderect(basket):
                   falling_objects.pop(i)
                   score += 1
                   if score % 10 == 0 and level < LEVEL_CAP:  # Increase level every 10 points
                       level += 1
                       speed_increase += 1
                       object_frequency = max(INITIAL_OBJECT_FREQUENCY - (level * 10), 20)  # Increase difficulty

Falling objects are updated in this part of the code. Each object’s position is moved downward based on its speed. If an object falls past the bottom of the screen, it’s removed, and the player loses a life. If the basket catches an object, the score increases, and the game may level up, increasing the difficulty by making objects fall faster and spawn more frequently.

       # If player reaches level 10 and completes it
       if level == LEVEL_CAP and score % 10 == 0 and score > 0:
           game_active = False
           game_won = True

Here, we check if the player has reached the maximum level and completed it. If so, the game is marked as won, and the victory screen will be displayed.

       # Update power-ups
       if game_active:
           # Iterate in reverse to safely remove items
           for i in range(len(power_ups) - 1, -1, -1):
               rect, kind = power_ups[i]
               rect.y += 5  # Move power-up downward
               if rect.y > HEIGHT:
                   power_ups.pop(i)
               elif rect.colliderect(basket):
                   power_ups.pop(i)
                   if kind == "increase_size":
                       basket.width = int(ORIGINAL_BASKET_WIDTH * 1.5)
                       power_up_timer = 300  # Basket stays larger for a short period
                   elif kind == "slow_down":
                       slow_down_timer = 300  # Slows down objects for a short period
                   elif kind == "extra_life":
                       lives += 1

This section handles the power-ups. Power-ups move downward similarly to falling objects. If a power-up collides with the basket, it applies its effect—such as increasing the basket size, slowing down falling objects, or granting an extra life. Each power-up effect has its own timer to ensure the effects are temporary, except for the extra life, which is permanent.

       # Handle power-up effects timing
       if power_up_timer > 0:
           power_up_timer -= 1
       else:
           reset_basket_size(basket)


       if slow_down_timer > 0:
           slow_down_timer -= 1
           # Update the speed of all objects
           for i in range(len(falling_objects)):
               rect, speed = falling_objects[i]
               falling_objects[i] = (rect, max(1, speed - 1))
       else:
           for i in range(len(falling_objects)):
               rect, _ = falling_objects[i]
               falling_objects[i] = (rect, random.randint(2, 5 + speed_increase))

Here, we manage the timing for power-up effects. Timers count down each frame, and once they reach zero, the effects are reverted. For example, the basket size returns to normal, and falling objects resume their regular speed.

       # Drawing
       if game_active:
           screen.fill(WHITE)
           # Draw basket and falling objects
           pygame.draw.rect(screen, BLUE, basket)
           draw_falling_objects(falling_objects)
           draw_power_ups(power_ups)


           # Display score, level, and lives
           score_text = font.render(f"Score: {score}", True, BLACK)
           level_text = font.render(f"Level: {level}", True, BLACK)
           lives_text = font.render(f"Lives: {lives}", True, BLACK)
           screen.blit(score_text, (10, 10))
           screen.blit(level_text, (10, 50))
           screen.blit(lives_text, (10, 90))

This part handles all the drawing operations when the game is active. It clears the screen, draws the basket, falling objects, and power-ups, and displays the player’s current score, level, and lives.

       elif not game_active and not game_over and not game_won:
           # Display start screen
           screen.fill(BLACK)
           title_text = large_font.render("Catch the Objects!", True, GREEN)
           screen.blit(title_text, (WIDTH // 2 - title_text.get_width() // 2, HEIGHT // 2 - 120))
           start_button_rect = draw_button("Start", WIDTH // 2 - 75, HEIGHT // 2 - 40, 150, 80, GREEN)

When the game is not active and hasn’t been won or lost, we display the start screen. This screen shows the game title and the start button, inviting the player to begin the game.

       elif game_over:
           # Display game over screen
           screen.fill(BLACK)
           game_over_text = large_font.render("Game Over", True, RED)
           screen.blit(game_over_text, (WIDTH // 2 - game_over_text.get_width() // 2, HEIGHT // 2 - 150))


           final_score_text = font.render(f"Final Score: {score}", True, WHITE)
           screen.blit(final_score_text, (WIDTH // 2 - final_score_text.get_width() // 2, HEIGHT // 2 - 50))


           restart_button_rect = draw_button("Restart", WIDTH // 2 - 75, HEIGHT // 2 + 20, 150, 80, GREEN)

If the player loses all lives, the game-over screen is shown. It displays a “Game Over” message, the final score, and a restart button so the player can try again.

       elif game_won:
           # Display congratulations screen
           screen.fill(BLACK)
           congrats_text = large_font.render("Congratulations! You Won!", True, GREEN)
           screen.blit(congrats_text, (WIDTH // 2 - congrats_text.get_width() // 2, HEIGHT // 2 - 150))


           final_score_text = font.render(f"Final Score: {score}", True, WHITE)
           screen.blit(final_score_text, (WIDTH // 2 - final_score_text.get_width() // 2, HEIGHT // 2 - 50))


           restart_button_rect = draw_button("Restart", WIDTH // 2 - 75, HEIGHT // 2 + 20, 150, 80, GREEN)

When the player successfully completes all levels, the victory screen is displayed. It congratulates the player, shows the final score, and provides a restart button to play again.

Finally, we update the display to reflect all the drawings and handle the game’s exit cleanly. The pygame.display.flip() function updates the entire screen, and pygame.quit() ensures that the game closes properly when the player exits.

    pygame.display.flip()

pygame.quit()

Running the Game

To complete our setup, we need to add a section that runs our game. This part checks if the script is being run directly (as opposed to being imported as a module) and starts the game by calling the game() function.

# Run the game
if __name__ == "__main__":
    game()

This ensures that the game will only start if this script is executed directly, not if it’s imported into another script.

Example

Full Code

import pygame
import random


# Initialize pygame
pygame.init()


# Constants
WIDTH, HEIGHT = 800, 600
FPS = 60
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)  # Power-up: Increase basket size
CYAN = (0, 255, 255)  # Power-up: Slow down falling objects
PURPLE = (255, 0, 255)  # Power-up: Extra life
BASKET_WIDTH, BASKET_HEIGHT = 100, 20
OBJECT_WIDTH, OBJECT_HEIGHT = 30, 30
POWERUP_SIZE = 25
ORIGINAL_BASKET_WIDTH = BASKET_WIDTH
MAX_OBJECTS = 5  # Maximum number of falling objects on screen at once
INITIAL_LIVES = 3
LEVEL_CAP = 10  # Level 10 is the final level
MINIMUM_OBJECT_GAP = 100  # Minimum horizontal distance between objects
INITIAL_OBJECT_FREQUENCY = 100  # Initial spawn frequency


# Set up display
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Catch the Falling Objects - The Pycodes")


# Load fonts
font = pygame.font.Font(None, 36)
large_font = pygame.font.Font(None, 72)


# Function to move the basket
def move_basket(basket, dx):
   basket.x += dx
   basket.x = max(0, min(WIDTH - basket.width, basket.x))



# Function to create a new falling object
def create_falling_object(speed_increase=0):
   rect = pygame.Rect(random.randint(0, WIDTH - OBJECT_WIDTH), 0, OBJECT_WIDTH, OBJECT_HEIGHT)
   speed = random.randint(2, 5 + speed_increase)
   return rect, speed



# Function to create a new power-up
def create_power_up():
   rect = pygame.Rect(random.randint(0, WIDTH - POWERUP_SIZE), 0, POWERUP_SIZE, POWERUP_SIZE)
   kind = random.choice(["increase_size", "slow_down", "extra_life"])
   return rect, kind



# Function to draw falling objects
def draw_falling_objects(falling_objects):
   for obj in falling_objects:
       pygame.draw.rect(screen, RED, obj[0])


# Function to draw power-ups
def draw_power_ups(power_ups):
   for pu in power_ups:
       if pu[1] == "increase_size":
           color = YELLOW
       elif pu[1] == "slow_down":
           color = CYAN
       elif pu[1] == "extra_life":
           color = PURPLE
       pygame.draw.rect(screen, color, pu[0])


# Function to reset basket size
def reset_basket_size(basket):
   basket.width = ORIGINAL_BASKET_WIDTH



# Button drawing function
def draw_button(text, x, y, width, height, color):
   rect = pygame.Rect(x, y, width, height)
   pygame.draw.rect(screen, color, rect)
   text_surf = font.render(text, True, WHITE)
   text_rect = text_surf.get_rect(center=rect.center)
   screen.blit(text_surf, text_rect)
   return rect



# Main game function
def game():
   clock = pygame.time.Clock()
   basket = pygame.Rect(WIDTH // 2, HEIGHT - BASKET_HEIGHT - 10, BASKET_WIDTH, BASKET_HEIGHT)
   falling_objects = []
   power_ups = []
   score = 0
   level = 1
   lives = INITIAL_LIVES
   speed_increase = 0
   power_up_timer = 0
   slow_down_timer = 0
   game_active = False
   game_over = False
   game_won = False  # Track whether the game was won
   object_frequency = INITIAL_OBJECT_FREQUENCY  # Use the initial frequency
   object_spawn_counter = 0


   # Buttons
   start_button_rect = draw_button("Start", WIDTH // 2 - 75, HEIGHT // 2 - 40, 150, 80, GREEN)
   restart_button_rect = draw_button("Restart", WIDTH // 2 - 75, HEIGHT // 2 - 40, 150, 80, GREEN)


   running = True
   while running:
       clock.tick(FPS)


       # Handle events
       for event in pygame.event.get():
           if event.type == pygame.QUIT:
               running = False
           if event.type == pygame.MOUSEBUTTONDOWN:
               if not game_active and not game_over and not game_won and start_button_rect.collidepoint(event.pos):
                   game_active = True
               if (game_over or game_won) and restart_button_rect.collidepoint(event.pos):
                   score, level, speed_increase, lives = 0, 1, 0, INITIAL_LIVES
                   reset_basket_size(basket)
                   falling_objects.clear()
                   power_ups.clear()
                   object_frequency = INITIAL_OBJECT_FREQUENCY  # Reset spawn frequency
                   object_spawn_counter = 0  # Reset spawn counter
                   game_active = True
                   game_over = False
                   game_won = False


       # Get keys
       keys = pygame.key.get_pressed()
       if game_active:
           if keys[pygame.K_LEFT]:
               move_basket(basket, -10)
           if keys[pygame.K_RIGHT]:
               move_basket(basket, 10)


       # Spawn new falling objects based on level and frequency
       if game_active:
           object_spawn_counter += 1
           if object_spawn_counter >= object_frequency and len(falling_objects) < MAX_OBJECTS:
               # Ensure the new object does not spawn too close to another object
               new_object = create_falling_object(speed_increase)
               if all(abs(new_object[0].x - obj[0].x) > MINIMUM_OBJECT_GAP for obj in falling_objects):
                   falling_objects.append(new_object)
                   object_spawn_counter = 0  # Reset the counter


           # Spawn power-ups occasionally
           if random.randint(0, 400) == 0:
               power_ups.append(create_power_up())


       # Update falling objects
       if game_active:
           # Iterate in reverse to safely remove items
           for i in range(len(falling_objects) - 1, -1, -1):
               rect, speed = falling_objects[i]
               rect.y += speed  # Move object downward
               if rect.y > HEIGHT:
                   falling_objects.pop(i)  # Remove object if it falls off the screen
                   lives -= 1
                   if lives <= 0:
                       game_active = False
                       game_over = True
               elif rect.colliderect(basket):
                   falling_objects.pop(i)
                   score += 1
                   if score % 10 == 0 and level < LEVEL_CAP:  # Increase level every 10 points
                       level += 1
                       speed_increase += 1
                       object_frequency = max(INITIAL_OBJECT_FREQUENCY - (level * 10), 20)  # Increase difficulty


       # If player reaches level 10 and completes it
       if level == LEVEL_CAP and score % 10 == 0 and score > 0:
           game_active = False
           game_won = True


       # Update power-ups
       if game_active:
           # Iterate in reverse to safely remove items
           for i in range(len(power_ups) - 1, -1, -1):
               rect, kind = power_ups[i]
               rect.y += 5  # Move power-up downward
               if rect.y > HEIGHT:
                   power_ups.pop(i)
               elif rect.colliderect(basket):
                   power_ups.pop(i)
                   if kind == "increase_size":
                       basket.width = int(ORIGINAL_BASKET_WIDTH * 1.5)
                       power_up_timer = 300  # Basket stays larger for a short period
                   elif kind == "slow_down":
                       slow_down_timer = 300  # Slows down objects for a short period
                   elif kind == "extra_life":
                       lives += 1


       # Handle power-up effects timing
       if power_up_timer > 0:
           power_up_timer -= 1
       else:
           reset_basket_size(basket)


       if slow_down_timer > 0:
           slow_down_timer -= 1
           # Update the speed of all objects
           for i in range(len(falling_objects)):
               rect, speed = falling_objects[i]
               falling_objects[i] = (rect, max(1, speed - 1))
       else:
           for i in range(len(falling_objects)):
               rect, _ = falling_objects[i]
               falling_objects[i] = (rect, random.randint(2, 5 + speed_increase))


       # Drawing
       if game_active:
           screen.fill(WHITE)
           # Draw basket and falling objects
           pygame.draw.rect(screen, BLUE, basket)
           draw_falling_objects(falling_objects)
           draw_power_ups(power_ups)


           # Display score, level, and lives
           score_text = font.render(f"Score: {score}", True, BLACK)
           level_text = font.render(f"Level: {level}", True, BLACK)
           lives_text = font.render(f"Lives: {lives}", True, BLACK)
           screen.blit(score_text, (10, 10))
           screen.blit(level_text, (10, 50))
           screen.blit(lives_text, (10, 90))


       elif not game_active and not game_over and not game_won:
           # Display start screen
           screen.fill(BLACK)
           title_text = large_font.render("Catch the Objects!", True, GREEN)
           screen.blit(title_text, (WIDTH // 2 - title_text.get_width() // 2, HEIGHT // 2 - 120))
           start_button_rect = draw_button("Start", WIDTH // 2 - 75, HEIGHT // 2 - 40, 150, 80, GREEN)


       elif game_over:
           # Display game over screen
           screen.fill(BLACK)
           game_over_text = large_font.render("Game Over", True, RED)
           screen.blit(game_over_text, (WIDTH // 2 - game_over_text.get_width() // 2, HEIGHT // 2 - 150))


           final_score_text = font.render(f"Final Score: {score}", True, WHITE)
           screen.blit(final_score_text, (WIDTH // 2 - final_score_text.get_width() // 2, HEIGHT // 2 - 50))


           restart_button_rect = draw_button("Restart", WIDTH // 2 - 75, HEIGHT // 2 + 20, 150, 80, GREEN)


       elif game_won:
           # Display congratulations screen
           screen.fill(BLACK)
           congrats_text = large_font.render("Congratulations! You Won!", True, GREEN)
           screen.blit(congrats_text, (WIDTH // 2 - congrats_text.get_width() // 2, HEIGHT // 2 - 150))


           final_score_text = font.render(f"Final Score: {score}", True, WHITE)
           screen.blit(final_score_text, (WIDTH // 2 - final_score_text.get_width() // 2, HEIGHT // 2 - 50))


           restart_button_rect = draw_button("Restart", WIDTH // 2 - 75, HEIGHT // 2 + 20, 150, 80, GREEN)


       pygame.display.flip()


   pygame.quit()


# Run the game
if __name__ == "__main__":
   game()

Happy Coding!

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top
×