Unit 12.3A · Term 3

Text & Scoring

Games need text for scores, instructions, and game-over screens. PyGame's pygame.font module renders text as image surfaces that you blit onto the screen.

Learning Objectives

  • 12.5.2.4 Output text to the application window
  • 12.5.3.7 Code score tracking and display

Lesson Presentation

12.3A-text-scoring.pdf · Slides for classroom use

Conceptual Anchor

The Rubber Stamp Analogy

PyGame text works like a rubber stamp: first you create the stamp (font.render()) — this produces an image of the text. Then you stamp it onto the canvas (screen.blit()) at a specific position.

Rules & Theory

Font Creation

Method Description Example
pygame.font.SysFont() Use a system font font = pygame.font.SysFont("Arial", 36)
pygame.font.Font() Use a custom .ttf file font = pygame.font.Font("pixel.ttf", 24)
pygame.font.Font(None, size) PyGame default font font = pygame.font.Font(None, 48)

Text Rendering Process

# Step 1: Create font object (do this ONCE, before the loop) font = pygame.font.SysFont("Arial", 36) # Step 2: Render text → creates a Surface text_surface = font.render("Hello!", True, (255, 255, 255)) # text antialias color # Step 3: Blit (draw) onto screen screen.blit(text_surface, (x, y))

Centering Text

# Get text dimensions text_rect = text_surface.get_rect() # Center on screen text_rect.center = (WIDTH // 2, HEIGHT // 2) screen.blit(text_surface, text_rect) # Other anchor points: # text_rect.topleft = (x, y) # text_rect.midtop = (x, y) # text_rect.topright = (x, y)

Worked Examples

1 Score Counter

import pygame, sys pygame.init() WIDTH, HEIGHT = 800, 600 screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Score Demo") clock = pygame.time.Clock() font = pygame.font.SysFont("Arial", 32) score = 0 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_SPACE: score += 10 # gain points screen.fill((30, 30, 30)) # Render and display score score_text = font.render(f"Score: {score}", True, (255, 255, 0)) screen.blit(score_text, (20, 20)) # Instructions hint = font.render("Press SPACE for points!", True, (150, 150, 150)) hint_rect = hint.get_rect(center=(WIDTH//2, HEIGHT//2)) screen.blit(hint, hint_rect) pygame.display.flip() clock.tick(60) pygame.quit() sys.exit()

2 Timer Display

import pygame, sys pygame.init() screen = pygame.display.set_mode((800, 600)) clock = pygame.time.Clock() font = pygame.font.SysFont("Arial", 48) start_ticks = pygame.time.get_ticks() # ms since start running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # Calculate elapsed seconds elapsed = (pygame.time.get_ticks() - start_ticks) / 1000 minutes = int(elapsed // 60) seconds = int(elapsed % 60) screen.fill((30, 30, 30)) timer_text = font.render(f"{minutes:02d}:{seconds:02d}", True, (0, 255, 100)) timer_rect = timer_text.get_rect(center=(400, 300)) screen.blit(timer_text, timer_rect) pygame.display.flip() clock.tick(60) pygame.quit() sys.exit()

3 Game Over Screen

def draw_game_over(screen, score): """Display centered game-over message.""" overlay = pygame.Surface((800, 600)) overlay.set_alpha(180) overlay.fill((0, 0, 0)) screen.blit(overlay, (0, 0)) big_font = pygame.font.SysFont("Arial", 72) small_font = pygame.font.SysFont("Arial", 28) # "GAME OVER" title title = big_font.render("GAME OVER", True, (255, 50, 50)) title_rect = title.get_rect(center=(400, 240)) screen.blit(title, title_rect) # Final score score_text = small_font.render(f"Final Score: {score}", True, (255, 255, 255)) score_rect = score_text.get_rect(center=(400, 320)) screen.blit(score_text, score_rect) # Restart hint hint = small_font.render("Press R to Restart", True, (150, 150, 150)) hint_rect = hint.get_rect(center=(400, 380)) screen.blit(hint, hint_rect)

Common Pitfalls

Creating Font INSIDE the Loop

Creating fonts is slow. Always create font objects before the game loop — only render() inside the loop.

Forgetting Anti-aliasing

The second argument of render() is anti-aliasing. Set it to True for smooth text edges, False for pixel-art style.

Tasks

Apply

Create a score display that increases by 10 when clicking the left mouse button and decreases by 5 with right click.

Apply

Add a countdown timer (30 seconds → 0) that displays "Time's Up!" when it reaches zero.

Create

Build a full HUD (heads-up display): score in top-left, timer in top-right, lives as hearts in top-center.

Self-Check Quiz

Q1: What two steps are needed to display text?

1) font.render("text", True, color) — creates a surface. 2) screen.blit(surface, (x, y)) — draws it on screen.

Q2: How do you center text on screen?

text_rect = text_surface.get_rect(center=(WIDTH//2, HEIGHT//2)) then screen.blit(text_surface, text_rect).

Q3: What does the second argument (True/False) in render() do?

Controls anti-aliasing: True = smooth text edges, False = jagged/pixelated edges.