Part 7 mini-project: Collect-All-Coins

The final project in the book combines every Part 7 concept: pygame drawing, keyboard input, collision detection, a list of game objects, and frame-based timing. Five coins sit on screen at once. A countdown timer runs in the corner. Collect all five before it hits zero to win.

What to build

When the program runs:

  1. Five coins appear at random positions on screen.
  2. The player (a blue square) moves with arrow keys.
  3. Walking into a coin removes it and adds 1 to the collected count.
  4. A countdown timer (30 seconds) is displayed in the top-right corner.
  5. If all five coins are collected before the timer reaches zero, a green "You win!" message fills the screen.
  6. If the timer reaches zero with coins remaining, a red "Time's up!" message fills the screen.
  7. Either outcome freezes the game for 3 seconds, then closes the window.

Files

projects/collect-all-coins/
    collect_all_coins.py

One file, no starter skeleton. Write it from scratch.

Run with:

python projects/collect-all-coins/collect_all_coins.py

How to approach it

  1. Get the window open and the player moving (same as Coin Collector).
  2. Create a list of five coin pygame.Rect objects with random positions.
  3. Draw every coin in the list each frame.
  4. On collision with any coin, remove it from the list.
  5. Add a frame counter: increment it each frame, divide by FPS to get elapsed seconds, subtract from 30 to get time remaining.
  6. Draw the timer text each frame.
  7. After the main loop, check whether the list is empty (win) or not (lose) and show the result screen.

Hints

  • Spawn coins in a loop:

    coins = []
    for _ in range(5):
        x = random.randint(padding, WIDTH - padding)
        y = random.randint(padding, HEIGHT - padding)
        coins.append(pygame.Rect(x - COIN_R, y - COIN_R, COIN_R * 2, COIN_R * 2))
  • Remove a coin on collision inside the game loop:

    coins = [c for c in coins if not player_rect.colliderect(c)]
  • Compute time remaining from a frame counter:

    frames += 1
    time_left = TIME_LIMIT - frames // FPS

    When time_left <= 0, break out of the game loop.

  • Win condition: if len(coins) == 0: break inside the game loop. After the loop, check which condition caused the exit to decide win or lose.

  • For the result screen, fill the background, render a large message, call pygame.display.flip(), then pygame.time.wait(3000) before quitting.

List comprehensions ([c for c in coins if ...]) are the cleanest way to remove items from a list while iterating. Deleting items with a regular for loop and remove() can skip entries — use the comprehension.

Draw coins as circles using their rect's center: pygame.draw.circle(screen, YELLOW, coin_rect.center, COIN_R). The rect is only used for collision; the visual is the circle.

Optional stretch goals

  • Two players. Add a second player (WASD keys) with their own score; first to three coins wins.
  • Timer bar. Draw a horizontal rectangle at the bottom of the screen that shrinks as time runs out; change it from green to red in the final 10 seconds.
  • Respawn round. After a win, wait 2 seconds, respawn five new coins, and reset the timer for another round. Track the round number.

None of these are required to finish the project.

Done?

When all five coins can be collected before the timer expires and the win screen appears — the project, and the book, are done.

You started with print("Hello") and ended with a working game. Every pygame tutorial from here uses the same loop, the same event handling, the same collision approach — just more objects, more state. Build something.