Login

Please fill in your details to login.





python breakout

Create the classic game of breakout using Python

Today, you are going to build a fully working Breakout game using Python 3. For this tutorial, you will be using Thonny, which is a fantastic environment for writing and running Python code. We will be using the built-in
turtle
module to draw the graphics.

As you follow along, you will notice placeholders in the code that look like this...

# Your comment: [Explain ...]


A huge part of learning to programme is understanding why the code works, so your task is to replace those brackets with your own notes explaining what that line or block of code is doing. Read the description at the start of each step carefully to help you figure it out!

Open up Thonny, create a new file, save it as
breakout.py
, and let's get started!

image
Classic Breakout

1
Setting up the Game Screen

Before we can draw any shapes or move any pieces, we need a blank canvas to work with. This step is designed to initialise the game window, set its size, give it a background colour, and title it. We also use a special command called
tracer(0)
. By default, the
turtle
module animates every single thing it draws. For a fast-paced game, this would look very jerky. By setting the tracer to zero, we turn off these automatic updates, allowing us to manually refresh the screen later on for perfectly smooth gameplay.

import turtle
import time

# Your comment: [Explain what the next line does]
wn = turtle.Screen()

# Your comment: [Explain what the next line does]
wn.title("Breakout  -  The Computing Café")

# Your comment: [Explain what the next line does]
wn.bgcolor("black")

# Your comment: [Explain what the next line does]
wn.setup(width=600, height=600)

# Your comment: [Explain what tracer(0) does for game animations]
wn.tracer(0)



2
Creating the Paddle

Now we create the player's paddle. In the
turtle
module, every object on the screen is technically a "turtle", but we can change its shape to look like a square. Because a standard square is too small for a paddle, we will use a function to stretch it out into a wide rectangle. We also lift the turtle's "pen" up so that it doesn't draw a solid line as it moves into its starting position at the bottom centre of the screen.

paddle = turtle.Turtle()

# Your comment: [Explain what speed(0) does]
paddle.speed(0)

# Your comment: [Explain the shape and colour functions]
paddle.shape("square")
paddle.color("blue")

# Your comment: [Explain what shapesize does here to make a rectangle]
paddle.shapesize(stretch_wid=1, stretch_len=5)

# Your comment: [Explain why we use penup()]
paddle.penup()

# Your comment: [Explain where goto() places the paddle]
paddle.goto(0, -250)



3
Creating the Ball

Next, we create the ball. Similar to the paddle, we change its shape to a circle and position it just above the paddle. We also give the ball two new variables:
dx
(change in x, or horizontal speed) and
dy
(change in y, or vertical speed). Notice that we are setting these to
0
initially. This means the ball will start completely stationary, waiting for the player to begin the game.

ball = turtle.Turtle()

# Your comment: [Explain these visual properties]
ball.speed(0)
ball.shape("circle")
ball.color("white")
ball.penup()
ball.goto(0, -200)

# Your comment: [Explain why dx and dy are set to 0 here]
ball.dx = 0
ball.dy = 0



4
The Message Display

We want to tell the player how to start the game. To do this, we create another turtle object. However, we don't actually want to see this turtle at all - we only want to use it to write text onto the screen! We will hide the turtle shape, move it to the centre of the screen, and use it to display a starting instruction.

message = turtle.Turtle()
message.speed(0)
message.color("white")
message.penup()

# Your comment: [Explain what hideturtle() does]
message.hideturtle()
message.goto(0, 0)

# Your comment: [Explain what the write() function does]
message.write("Press Space to Start", align="center", font=("Courier", 24, "normal"))



5
Building the Wall of Bricks

A game of Breakout isn't complete without bricks to smash! Instead of writing the code for a brick 44 separate times, we use a programming technique called a "nested loop" (a loop inside a loop). The outer loop will run 4 times to create 4 rows. The inner loop will run 11 times to create 11 columns. As each brick is generated, it is coloured based on its row and added to an empty list so the computer can keep track of it later.

# Your comment: [Explain what an empty list is used for here]
bricks = []

# Your comment: [Explain this list of colours]
colours = ["red", "orange", "yellow", "green"]

# Your comment: [Explain how many times this outer loop runs]
for y in range(4):
    
    # Your comment: [Explain how many times this inner loop runs]
    for x in range(-5, 6):
        brick = turtle.Turtle()
        brick.speed(0)
        brick.shape("square")
        
        # Your comment: [Explain how the colour is chosen using the 'y' variable]
        brick.color(colours[y])
        brick.shapesize(stretch_wid=1, stretch_len=2)
        brick.penup()
        
        # Your comment: [Explain the maths used to place the brick on the screen]
        brick.goto(x * 50, 250 - (y * 30))
        
        # Your comment: [Explain what append() does]
        bricks.append(brick)



6
Adding Player Controls

You need to be able to interact with the game! Here, we define three functions (blocks of reusable code). Two functions will move the paddle left and right by checking its current coordinate and adding or subtracting pixels. The third function will release the ball by changing its speed from 0 to 3, but only if it is currently stationary. Finally, we tell the computer screen to "listen" for keyboard inputs and link our functions to specific keys.

def paddle_right():
    # Your comment: [Explain what xcor() does]
    x = paddle.xcor()
    
    # Your comment: [Explain this if statement]
    if x < 240:
        x += 40
        # Your comment: [Explain what setx() does]
        paddle.setx(x)

def paddle_left():
    x = paddle.xcor()
    
    # Your comment: [Explain this if statement]
    if x > -240:
        x -= 40
        paddle.setx(x)

def release_ball():
    # Your comment: [Explain the logic of this function]
    if ball.dx == 0 and ball.dy == 0:
        message.clear()
        ball.dx = 3
        ball.dy = 3

# Your comment: [Explain what listen() does]
wn.listen()

# Your comment: [Explain how the keys are bound to the functions]
wn.onkeypress(paddle_right, "Right")
wn.onkeypress(paddle_left, "Left")
wn.onkeypress(release_ball, "space")



7
The Main Game Loop & Wall Collisions

This is the engine of your game. The
while True:
loop will run continuously forever. Inside this loop, we update the screen, add a tiny pause (
time.sleep
) so the game runs at a playable speed, and move the ball. We also use
if
statements to check if the ball has touched the top, left, or right edges of the screen, reversing its direction if it has. If it touches the bottom edge, it means the player missed it, so we reset everything back to the centre.

while True:
    # Your comment: [Explain why we need to update the screen constantly]
    wn.update()
    
    # Your comment: [Explain what time.sleep() does for the game speed]
    time.sleep(0.01)

    # Your comment: [Explain how the ball moves using its current position and its speed]
    ball.setx(ball.xcor() + ball.dx)
    ball.sety(ball.ycor() + ball.dy)

    # Your comment: [Explain this top border check]
    if ball.ycor() > 290:
        ball.sety(290)
        ball.dy *= -1

    # Your comment: [Explain these side border checks]
    if ball.xcor() > 290:
        ball.setx(290)
        ball.dx *= -1
        
    if ball.xcor() < -290:
        ball.setx(-290)
        ball.dx *= -1

    # Your comment: [Explain what happens when the ball hits the bottom edge]
    if ball.ycor() < -290:
        ball.goto(0, -200)
        ball.dx = 0
        ball.dy = 0
        paddle.goto(0, -250)
        message.write("Press Space", align="center", font=("Courier", 24, "normal"))



8
Paddle and Brick Collisions

Finally, we need to program the physics of hitting objects. The computer doesn't automatically know when two shapes touch; we have to tell it the exact mathematical coordinates that count as a "hit". Important: This code belongs inside the
while True:
loop. Make sure you indent it carefully in Thonny so it aligns with the code from Step 7!

    # Your comment: [Explain the mathematical logic for the paddle collision]
    if (ball.ycor() > -240 and ball.ycor() < -230) and (ball.xcor() < paddle.xcor() + 50 and ball.xcor() > paddle.xcor() - 50):
        ball.sety(-230)
        ball.dy *= -1

    # Your comment: [Explain what this for loop does]
    for brick in bricks:
        
        # Your comment: [Explain the logic for the brick collision]
        if (ball.ycor() > brick.ycor() - 15 and ball.ycor() < brick.ycor() + 15) and (ball.xcor() > brick.xcor() - 25 and ball.xcor() < brick.xcor() + 25):
            
            # Your comment: [Explain how the ball bounces]
            ball.dy *= -1
            
            # Your comment: [Explain why we move the brick far off the screen]
            brick.goto(1000, 1000)
            
            # Your comment: [Explain why we remove it from the list and use 'break']
            bricks.remove(brick)
            break



Once you have written in all of your comments and carefully checked your indentation inside the main loop, click "Run" in Thonny to test your game! Read Thonny's error messages closely to debug your code if things don't work the first time.

image

Hungry for more?


Finished early? Your Breakout game works, but it is missing a few classic arcade features. Pick one or more of the challenges below to upgrade your project. You will need to think carefully about where in your existing code these new instructions belong.

Keep Score: Create a new
turtle
object to act as a scoreboard and place it at the top of the screen. Create a
score
variable starting at 0, use the
turtle.write()
function to display it, and increase the score by 10 every time a brick is destroyed. You will need to clear the old score before writing the new one!
Multiple Lives: Right now, the ball resets forever. Create a
lives
variable set to 3. Modify the bottom border collision code so that it subtracts a life each time the ball drops. When lives reach 0, clear the screen and display a "Game Over" message.
Need for Speed: Make the game progressively harder to test the player's reflexes. Add logic inside your brick collision loop that slightly increases both
ball.dx
and
ball.dy
(for example, by adding 0.5) every time a brick is removed from the list.
Value the Colours: In the original Breakout arcade game, the higher bricks were worth more points. Modify your scoring system so that red bricks are worth 40 points, orange 30, yellow 20, and green 10. You will need to check the brick's colour attribute during the collision check to decide how many points to add.
Design a New Level: Once all the bricks are gone, the game currently just leaves an empty screen. Write a function that automatically redraws a brand new layout of bricks - perhaps in a triangle or a diamond shape - once the length of the
bricks
list reaches zero.
Add Sound Effects: A true arcade game needs sound! Depending on the operating system you are using, research how to import the
winsound
module (for Windows) or use the
os
module (for macOS/Linux) to trigger a short 'beep' sound whenever the ball collides with the paddle or a wall.
Last modified: June 26th, 2026
The Computing Café works best in landscape mode.
Rotate your device.
Dismiss Warning