No history yet

Implementing Game Mechanics

Making Things Interact

So far, we've created a game window, drawn some shapes, and even made them move with keyboard input. But games get interesting when objects start interacting with each other. The most fundamental type of interaction is a collision. Did the player just grab a coin? Did an enemy laser hit the spaceship? Answering these questions starts with collision detection.

In Pygame, the easiest way to detect collisions is by using Rect objects. A Rect is just a rectangle that stores the position and dimensions of an object. You can think of it as an invisible box around your player, enemies, or items. If these boxes overlap, we know a collision has occurred.

Every sprite or image you load can have a Rect associated with it. Pygame's Rect objects have a handy method called colliderect(). You give it another Rect, and it returns True if they are overlapping and False if they are not. It's that simple.

# Assume player_rect and coin_rect are pygame.Rect objects
# updated each frame to match their sprite's position.

if player_rect.colliderect(coin_rect):
    print("Player picked up the coin!")
    # Here you would remove the coin and add to the score

Keeping Score

Once you can detect collisions, you can start building game mechanics around them. A scoring system is a common example. At its heart, a score is just a number stored in a variable that changes when the player does something right, like collecting a coin.

The key is to initialize the score variable to zero at the start of the game, and then increment it whenever a scoring event happens.

But a score isn't much good if the player can't see it. To display the score, you'll need to use Pygame's font capabilities. You first create a font object, then use that font to render() your score text into a new Surface. A Surface is Pygame's word for any image or block of pixels. Finally, you blit() (copy) that text Surface onto your main screen Surface.

import pygame

pygame.init()
screen = pygame.display.set_mode((800, 600))

# --- Setup ---
score = 0
# Use a default font, size 36
font = pygame.font.Font(None, 36)

# --- Game Loop ---
running = True
while running:
    # ... event handling and game logic ...
    
    # Example: increment score when 'c' key is pressed
    # In a real game, this would happen on collision
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_c:
                score += 10
    
    # --- Drawing ---
    screen.fill((0, 0, 0)) # Black background
    
    # Create a surface with the score text
    score_text = f"Score: {score}"
    text_surface = font.render(score_text, True, (255, 255, 255)) # White text
    
    # Draw the text surface onto the screen at position (10, 10)
    screen.blit(text_surface, (10, 10))
    
    pygame.display.flip()

pygame.quit()

Managing the Game's Flow

Most games aren't just one endless screen of action. They have a start menu, a main gameplay section, a game over screen, and maybe even a pause menu. These different parts of the game are called game states. Managing the flow between these states is crucial for a complete game experience.

A simple but effective way to handle this is with a state variable. You can create a variable, say game_state, that holds a string representing the current state, like "start_menu", "playing", or "game_over".

Inside your main game loop, you'll use if statements to check the value of game_state. Based on the state, you'll run different code for event handling, updating game logic, and drawing to the screen. For example, if the state is "start_menu", you'll draw the title and a "Press Start" message. If the state is "game_over", you'll show the final score and an option to restart.

# Inside the main game loop

game_state = "start_menu"

while running:
    # --- Event Handling ---
    # This part can change the game_state
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if game_state == "start_menu":
                if event.key == pygame.K_RETURN:
                    game_state = "playing"
            elif game_state == "game_over":
                if event.key == pygame.K_r:
                    # Reset the game and go to start menu
                    score = 0
                    game_state = "start_menu"
    
    # --- Drawing and Logic based on state ---
    if game_state == "start_menu":
        screen.fill((0, 0, 100)) # Dark blue background
        # Draw title and instructions
    elif game_state == "playing":
        screen.fill((0, 0, 0)) # Black background
        # Run all the main game logic and drawing
        # If player loses, change state: game_state = "game_over"
    elif game_state == "game_over":
        screen.fill((100, 0, 0)) # Dark red background
        # Draw "Game Over", final score, and restart instructions
        
    pygame.display.flip()
Quiz Questions 1/5

In Pygame, what is the most common method used on a Rect object to check if it is overlapping with another Rect object?

Quiz Questions 2/5

What is a common and effective way to manage different parts of a game, like a start menu, the main gameplay, and a game over screen?

With these three concepts—collision detection, scoring, and state management—you have the essential toolkit to build the core logic for a wide variety of simple games.