Pygame Zero: Falling Objects Game

This game involves catching falling stars and avoiding bombs. Players control a basket that moves left and right using arrow keys. Here's a breakdown of the code:

Importing Modules

We import the necessary modules: random for generating random values and pgzrun to run the Pygame Zero game:

import random
import pgzrun

Setting Up the Game

The screen size, basket, falling objects, score, and game state are initialized as follows:

WIDTH = 200
HEIGHT = 300
basket = Rect((WIDTH // 2 - 20, HEIGHT - 30), (40, 10))
objects = []
object_speed = 2
object_types = ["star", "bomb"]
score = 0
game_running = True

Spawning Falling Objects

The spawn_object() function generates a random object (either a star or a bomb) at a random position at the top of the screen:

def spawn_object():
    x = random.randint(0, WIDTH - 10)
    obj_type = random.choice(object_types)
    objects.append({"rect": Rect((x, -10), (10, 10)), "type": obj_type})

Drawing Game Elements

The draw() function displays the basket, objects, score, and game-over message (if applicable):

def draw():
    screen.clear()
    screen.draw.filled_rect(basket, "blue")
    for obj in objects:
        if obj["type"] == "star":
            screen.draw.filled_rect(obj["rect"], "yellow")
        elif obj["type"] == "bomb":
            screen.draw.filled_rect(obj["rect"], "red")
    screen.draw.text(f"Score: {score}", (10, 10), color="white", fontsize=20)
    if not game_running:
        screen.draw.text("GAME OVER", center=(WIDTH // 2, HEIGHT // 2), color="white", fontsize=30)

Updating the Game State

The update() function is the heart of the game logic. It handles movement, collision detection, scoring, and gradually increases the game's difficulty:

1. Checking if the Game is Running

If the game is over, no further updates are processed:

if not game_running:
    return

2. Moving the Basket

The basket is moved left or right with the arrow keys, ensuring it stays within screen bounds:

if keyboard.left and basket.left > 0:
    basket.x -= 4
if keyboard.right and basket.right < WIDTH:
    basket.x += 4
  • keyboard.left: Detects if the left arrow key is pressed.
  • basket.left > 0: Prevents the basket from moving off the left edge.
  • basket.right < WIDTH: Prevents the basket from moving off the right edge.

3. Moving Falling Objects

Each falling object moves down by a fixed speed:

for obj in objects[:]:
    obj["rect"].y += object_speed

4. Handling Collisions

Objects are checked for collisions with the basket or the bottom of the screen:

if obj["rect"].colliderect(basket):
    if obj["type"] == "star":
        score += 1
    elif obj["type"] == "bomb":
        game_running = False
    objects.remove(obj)
elif obj["rect"].top > HEIGHT:
    objects.remove(obj)
  • obj["rect"].colliderect(basket): Detects if the object touches the basket.
  • obj["type"] == "star": Increases the score if the object is a star.
  • obj["type"] == "bomb": Ends the game if the object is a bomb.

5. Gradually Increasing Difficulty

The speed of falling objects increases slightly every 10 points:

if score % 10 == 0 and score > 0:
    global object_speed
    object_speed += 0.01

Ending the Game

The game ends when the player catches a bomb, and the game_running flag is set to False:

def game_over():
    global game_running
    game_running = False

Spawning Objects Periodically

Objects are spawned every second using a timer:

clock.schedule_interval(spawn_object, 1.0)

Starting the Game

The game starts with the pgzrun.go() function:

pgzrun.go()