Movement & Animation
Animation in PyGame works by changing object coordinates each frame. Move an object by adding velocity to its position on every loop iteration — clear, move, redraw.
Learning Objectives
- 12.5.3.1 Code the movement of graphic objects
- 12.5.3.8 Analyse the result of the programme execution
Conceptual Anchor
The Flipbook Analogy
A flipbook creates motion by drawing a figure in slightly different positions on each page. PyGame animation works the same way: erase old position → draw at new position → show frame. The velocity is how far the figure moves between each page.
Rules & Theory
Movement Formula
# Each frame:
x = x + vel_x # horizontal movement
y = y + vel_y # vertical movement
# vel_x > 0 → moving right vel_x < 0 → moving left
# vel_y > 0 → moving down vel_y < 0 → moving upBoundary Handling
| Strategy | Behavior | Code Pattern |
|---|---|---|
| Bounce | Reverse direction at edges | if x > WIDTH: vel_x = -vel_x |
| Wrap | Appear on opposite side | x = x % WIDTH |
| Clamp | Stop at edge | x = max(0, min(x, WIDTH)) |
| Destroy | Remove object when offscreen | if x > WIDTH: objects.remove(obj) |
Worked Examples
1 Bouncing Ball
import pygame, sys
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Bouncing Ball")
clock = pygame.time.Clock()
# Ball properties
ball_x, ball_y = 400, 300
ball_radius = 20
vel_x, vel_y = 4, 3
BLUE = (50, 100, 255)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# UPDATE: move ball
ball_x += vel_x
ball_y += vel_y
# Bounce off walls
if ball_x - ball_radius <= 0 or ball_x + ball_radius >= WIDTH:
vel_x = -vel_x
if ball_y - ball_radius <= 0 or ball_y + ball_radius >= HEIGHT:
vel_y = -vel_y
# RENDER
screen.fill((0, 0, 0))
pygame.draw.circle(screen, BLUE, (ball_x, ball_y), ball_radius)
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()2 Moving Square (with Rect)
import pygame, sys
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
# Using pygame.Rect for the object
player = pygame.Rect(100, 100, 50, 50)
vel_x, vel_y = 3, 2
RED = (255, 50, 50)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Move
player.x += vel_x
player.y += vel_y
# Bounce using Rect properties
if player.left <= 0 or player.right >= WIDTH:
vel_x = -vel_x
if player.top <= 0 or player.bottom >= HEIGHT:
vel_y = -vel_y
# Draw
screen.fill((30, 30, 30))
pygame.draw.rect(screen, RED, player)
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()3 Analyzing Code — Trace the Output
# Question: What does this code do?
x, y = 0, 300
vel_x = 5
while running:
x += vel_x
if x > 800:
x = 0
pygame.draw.circle(screen, RED, (x, y), 10)
# Answer: Draws a red circle moving RIGHT at speed 5.
# When it goes past x=800, it WRAPS back to x=0.
# The circle moves horizontally along y=300 (middle).
# This is a "wrap" boundary strategy.Common Pitfalls
Forgetting screen.fill() Before Drawing
If you don't clear the screen each frame, old positions remain visible — you'll see a "trail" of the moving object instead of clean animation.
Bounce Misses the Radius
For circles, check x - radius and x + radius, not just x.
Otherwise the ball partially exits the screen before bouncing.
Tasks
Create a ball that bounces around the screen. Add gravity (increase vel_y by 0.1
each frame).
Create 3 balls with different speeds and colors, all bouncing independently.
Given a code snippet with x += 3 and y -= 2, trace the object's
path over 10 frames and describe its direction.
Self-Check Quiz
Q1: How do you make an object move right?
x += vel_x where vel_x > 0.Q2: How do you make an object bounce off the right wall?
if x + radius >= WIDTH: vel_x = -vel_x — reverse the horizontal velocity when the
object reaches the right edge.Q3: What is the difference between bounce and wrap?