10. pygame Basics

Everything so far has been text in the console. pygame lets you open a window and draw shapes that move. This is how you’ll actually see your evolution sim.


First, get pygame ready

pygame is an extra toolbox that doesn’t come with Python. You install it once by typing this into a terminal (ask your grown-up to help the first time):

pip install pygame

Then, at the top of your file, bring it in:

import pygame

How screen positions work

The window is a grid of tiny dots called pixels. You describe a position with two numbers: x (how far across) and y (how far down).

⚠️ One surprise: y counts downwards! The very top of the window is y = 0, and y gets bigger as you go down. So a bigger y means lower on the screen.

(0, 0) is the TOP-LEFT corner
  x →  gets bigger going right
  y ↓  gets bigger going DOWN

Colours

A colour is three numbers: how much Red, Green, and Blue it has, each from 0 to 255. This is called RGB.

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 200, 0)
BLUE = (50, 100, 255)

Notice these are written in CAPITALS because they’re constants — they don’t change.


The skeleton every pygame program needs

Almost every pygame program has the same shape. Here it is, fully explained. This opens a window that just sits there until you close it.

import pygame

# ---- constants ----
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
BACKGROUND_COLOUR = (30, 30, 40)

# ---- set up ----
pygame.init()
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("My Creature World")
clock = pygame.time.Clock()

# ---- the game loop ----
is_running = True
while is_running:

    # 1. check what the player is doing
    for event in pygame.event.get():
        if event.type == pygame.QUIT:      # they clicked the X to close
            is_running = False

    # 2. paint the whole background over the old frame
    screen.fill(BACKGROUND_COLOUR)

    # 3. (we'll draw our creatures here soon)

    # 4. show the new picture
    pygame.display.flip()

    # 5. wait a tiny bit so the game runs at 60 frames per second
    clock.tick(60)

# ---- tidy up when the loop ends ----
pygame.quit()

What is the “game loop”?

That big while is_running: loop is the heart of every game. It runs about 60 times every second. Each time round is called a frame. In every frame you:

  1. Check input — did the player press a key or close the window?
  2. Update — move things, change energy, etc.
  3. Draw — paint the new picture.

Do that 60 times a second and shapes appear to move smoothly. It’s like a flip-book!

Remember while loops from 4. Loops? This is exactly that. The loop keeps going while is_running is True. When the player clicks the X, we set is_running = False, and the loop stops.


Drawing shapes

You draw inside the game loop, after screen.fill(...) and before pygame.display.flip().

A circle (great for a creature!)

# pygame.draw.circle(where, colour, (x, y), radius)
pygame.draw.circle(screen, (0, 200, 0), (400, 300), 20)

This draws a green circle, 20 pixels wide, in the middle of an 800×600 window.

A rectangle (great for food, or the world)

# pygame.draw.rect(where, colour, (x, y, width, height))
pygame.draw.rect(screen, (200, 150, 0), (100, 100, 40, 40))

This draws a small orange square near the top-left.


Making something move

To move a shape, keep its position in variables and change them a little every frame. Because you redraw 60 times a second, it looks like smooth movement.

Here’s a complete, runnable program: a green creature-circle that drifts across the screen and bounces off the edges.

import pygame

WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
BACKGROUND_COLOUR = (30, 30, 40)
CREATURE_COLOUR = (0, 200, 0)
CREATURE_RADIUS = 20

pygame.init()
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Moving Creature")
clock = pygame.time.Clock()

# the creature's starting position and how fast it moves each frame
creature_x = 100
creature_y = 300
speed_x = 3
speed_y = 2

is_running = True
while is_running:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            is_running = False

    # --- update: move the creature ---
    creature_x += speed_x
    creature_y += speed_y

    # bounce off the left/right walls by flipping the direction
    if creature_x < CREATURE_RADIUS or creature_x > WINDOW_WIDTH - CREATURE_RADIUS:
        speed_x = -speed_x

    # bounce off the top/bottom walls
    if creature_y < CREATURE_RADIUS or creature_y > WINDOW_HEIGHT - CREATURE_RADIUS:
        speed_y = -speed_y

    # --- draw ---
    screen.fill(BACKGROUND_COLOUR)
    pygame.draw.circle(screen, CREATURE_COLOUR, (creature_x, creature_y), CREATURE_RADIUS)
    pygame.display.flip()

    clock.tick(60)

pygame.quit()

Run it and watch your creature bounce around the window! 🎉

Try changing speed_x and speed_y to make it faster, slower, or move in a different direction.


Connecting this to your Creature class

Here’s the exciting part. Remember the Creature class from 8. Classes & Objects? You can give each creature its own x, y, and colour, keep them all in a list, and draw the whole population every frame with a for loop:

import pygame
import random

WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
BACKGROUND_COLOUR = (30, 30, 40)


class Creature:
    def __init__(self, x, y, speed):
        self.x = x
        self.y = y
        self.speed = speed
        self.energy = 100

    def move(self):
        # take a small random step in x and y
        self.x += random.randint(-self.speed, self.speed)
        self.y += random.randint(-self.speed, self.speed)

    def draw(self, screen):
        pygame.draw.circle(screen, (0, 200, 0), (self.x, self.y), 10)


pygame.init()
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Creature World")
clock = pygame.time.Clock()

# make 15 creatures in random spots
creatures = []
for creature_number in range(15):
    start_x = random.randint(0, WINDOW_WIDTH)
    start_y = random.randint(0, WINDOW_HEIGHT)
    creatures.append(Creature(start_x, start_y, 3))

is_running = True
while is_running:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            is_running = False

    screen.fill(BACKGROUND_COLOUR)

    # give every creature a turn, then draw it
    for creature in creatures:
        creature.move()
        creature.draw(screen)

    pygame.display.flip()
    clock.tick(60)

pygame.quit()

And there it is — a window full of little creatures, each one an object, all wandering around. From here you can add food, energy loss, eating, and babies, and you’ve got the beginnings of a real evolution sim. 🌍


✅ Quick recap

  • Install once with pip install pygame, then import pygame.
  • Positions are (x, y); y gets bigger going down.
  • Colours are (red, green, blue), each 0–255.
  • Every pygame program has a game loop (a while loop) that runs ~60 times a second.
  • Each frame: check events → update → screen.fill() → draw → pygame.display.flip()clock.tick(60).
  • Move things by changing their position variables a little each frame.
  • Give your Creature class a draw(self, screen) method and loop over a list to draw them all.