32. Drawing on screen
With a window open and a game loop running, the next step is putting something visible on the screen. pygame provides drawing functions for rectangles, circles, lines, and polygons. All of them follow the same pattern: tell pygame which surface to draw on, what colour to use, and where to put it.
The coordinate system
pygame uses a coordinate system where (0, 0) is the
top-left corner of the window. The x-axis increases to
the right and the y-axis increases downward. This is
common in 2D graphics but opposite to the maths convention where y
increases upward.
(0,0) ──────────────────► x
│
│
│
▼
y
For an 800x600 window:
- Top-left corner:
(0, 0) - Top-right corner:
(799, 0) - Bottom-left corner:
(0, 599) - Bottom-right corner:
(799, 599) - Centre:
(400, 300)
When you position a shape, you are giving pixel coordinates in this system.
Colours as RGB tuples
Every colour in pygame is a tuple of three integers:
(red, green, blue). Each component ranges from 0 (none) to
255 (full).
| Colour | Tuple |
|---|---|
| Black | (0, 0, 0) |
| White | (255, 255, 255) |
| Red | (255, 0, 0) |
| Green | (0, 255, 0) |
| Blue | (0, 0, 255) |
| Yellow | (255, 255, 0) |
| Cyan | (0, 255, 255) |
| Magenta | (255, 0, 255) |
| Orange | (255, 165, 0) |
| Dark grey | (64, 64, 64) |
Mix components to get any colour you want.
(200, 100, 50) is a brownish orange;
(30, 30, 80) is a dark navy.
Store colours in variables at the top of your file to avoid repeating the tuple everywhere:
RED = (255, 0, 0)
GREEN = (0, 200, 0)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
SKY = (135, 206, 235)Drawing functions
All drawing functions live in pygame.draw. Call them
inside the game loop, after
screen.fill(...) (which clears the canvas) and
before pygame.display.flip() (which shows
the frame).
Rectangle
pygame.draw.rect(screen, color, (x, y, width, height))x,y— position of the top-left corner of the rectangle.width,height— size in pixels.
pygame.draw.rect(screen, (255, 0, 0), (100, 150, 200, 80))Draws a red rectangle with its top-left corner at
(100, 150), 200 pixels wide and 80 pixels tall.
Add a fifth argument for the line thickness. Thickness 0
(the default) fills the shape; any positive value draws only the
outline:
pygame.draw.rect(screen, (255, 255, 255), (100, 150, 200, 80), 3)Circle
pygame.draw.circle(screen, color, (center_x, center_y), radius)center_x,center_y— position of the centre.radius— radius in pixels.
pygame.draw.circle(screen, (255, 255, 0), (400, 300), 50)Draws a yellow filled circle centred at (400, 300) with
radius 50. Same as rectangles, an optional thickness argument draws an
outline only.
Line
pygame.draw.line(screen, color, (x1, y1), (x2, y2), thickness)pygame.draw.line(screen, (255, 255, 255), (0, 0), (799, 599), 2)Draws a white line from the top-left to the bottom-right corner, 2 pixels thick.
Polygon
pygame.draw.polygon(screen, color, [(x1,y1), (x2,y2), (x3,y3), ...])Takes a list of vertex tuples and draws a filled shape connecting them in order. Good for triangles:
pygame.draw.polygon(screen, (200, 100, 50), [(400, 100), (300, 250), (500, 250)])This draws a triangle pointing upward.
Drawing order matters
pygame draws shapes in the order you call the draw functions. A shape drawn later appears on top of a shape drawn earlier. There is no z-layer concept — just call order.
screen.fill((0, 0, 0))
# Draw the background rectangle first
pygame.draw.rect(screen, (0, 100, 200), (50, 50, 300, 200))
# Draw the circle on top of it
pygame.draw.circle(screen, (255, 255, 0), (200, 150), 60)The yellow circle is partially over the blue rectangle. Swap the two calls and the rectangle covers the circle.
Using variables for position and size
Hard-coding numbers directly in draw calls makes the code brittle. Store position and size in variables instead:
x = 100
y = 200
width = 60
height = 60
color = (255, 0, 0)
pygame.draw.rect(screen, color, (x, y, width, height))Now you can move the square by changing x and
y. Later chapters will update these variables every frame
to make things move.
Open exercises/32/01-scene.py. Draw a simple house
scene:
- A large rectangle for the house body.
- A triangle (polygon) for the roof above it.
- A small rectangle for the door.
- A yellow circle for the sun in one corner.
Adjust the coordinates and colours until the scene looks reasonable. No artistic talent required — getting the coordinates in the right order is the exercise.
A complete drawing example
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Drawing")
clock = pygame.time.Clock()
SKY = (135, 206, 235)
GROUND = (34, 139, 34)
BROWN = (139, 90, 43)
RED = (200, 50, 50)
YELLOW = (255, 220, 0)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Clear
screen.fill(SKY)
# Ground
pygame.draw.rect(screen, GROUND, (0, 450, 800, 150))
# House body
pygame.draw.rect(screen, BROWN, (300, 280, 200, 170))
# Roof (triangle)
pygame.draw.polygon(screen, RED, [(280, 280), (400, 160), (520, 280)])
# Sun
pygame.draw.circle(screen, YELLOW, (700, 80), 50)
pygame.display.flip()
clock.tick(60)
pygame.quit()Homework
Problem 1 — Flag
Open exercises/32/homework/01-flag.py. Draw a simple
three-stripe flag filling most of the window. Each stripe should be a
different colour. Use pygame.draw.rect for each stripe.
Problem 2 — Target
Open exercises/32/homework/02-target.py. Draw a target:
three concentric circles (one inside the other, centred at the same
point) in alternating colours — for example red, white, red, or any
colours you choose. The outermost circle should be the largest; the
innermost the smallest.
Problem 3 — Grid
Open exercises/32/homework/03-grid.py. Draw a 4x4 grid
of squares covering the window. Use nested for loops to
calculate each square's position. All squares can be the same colour,
but draw their outlines (use a positive thickness argument) so you can
see the grid lines.
Challenge — Chessboard
Open exercises/32/homework/04-chessboard.py. Draw an 8x8
chessboard. Squares at positions where (row + col) % 2 == 0
are white; the rest are dark. Use nested for loops. The
board should fill the window neatly.
Stuck or finished? Open the homework solutions page.