In this project, we built a simple version of Pong, one of the earliest video games, using Python's built-in turtle module. It's an excellent introduction to animation, game loops, event handling, and collision detection.
This project helps beginners understand how a real-time game can be created from scratch—no external libraries needed.
What You'll Learn
Setting up a basic game screen using turtle.Screen()
Drawing and moving paddles with keyboard input
Animating a bouncing ball
Detecting collisions with walls and paddles
Keeping and displaying a live score
Using variables and conditionals to control game logic
How We Coded It
We started by importing the turtle module and creating a window with a black background and a title. Then, we created two paddle objects and a ball:
Each paddle can be moved up and down using the W/S keys (Player A) and Arrow Up/Down keys (Player B). The movement is done using onkeypress() bindings.
To animate the ball, we used a while True game loop, where the ball continuously updates its position based on its dx and dy values. When it hits the top or bottom walls, it bounces back by reversing its vertical direction.
Collision detection is handled using simple boundary checks:
if (340 < ball.xcor() < 350) and (paddle_b.ycor() - 50 < ball.ycor() < paddle_b.ycor() + 50):
# Bounce off right paddle
Scores are kept in two variables, score_a and score_b, and displayed at the top of the screen using another turtle object.
We also introduced a speed multiplier to make the game more exciting—the ball speeds up slightly with every bounce.
Possible Extensions
If you're interested in taking it further, you could:
Add sound effects
Create a main menu or game over screen
Add difficulty levels or a countdown timer
Turn it into a two-player online game using sockets
Problems
Full Python Code
import turtle
# Set up the screen
wn = turtle.Screen()
wn.title("Pong")
wn.bgcolor("black")
wn.setup(width=800, height=600)
# Score variables
score_a = 0
score_b = 0
# Initial speed settings
initial_speed = 4
speed_multiplier = 1.05
# Paddle A
paddle_a = turtle.Turtle()
paddle_a.speed(0)
paddle_a.shape("square")
paddle_a.color("white")
paddle_a.shapesize(stretch_wid=6, stretch_len=1)
paddle_a.penup()
paddle_a.goto(-350, 0)
# Paddle B
paddle_b = turtle.Turtle()
paddle_b.speed(0)
paddle_b.shape("square")
paddle_b.color("white")
paddle_b.shapesize(stretch_wid=6, stretch_len=1)
paddle_b.penup()
paddle_b.goto(350, 0)
# Ball
ball = turtle.Turtle()
ball.speed(0)
ball.shape("square")
ball.color("white")
ball.penup()
ball.goto(0, 0)
ball.dx = initial_speed
ball.dy = initial_speed
# Score display
score_display = turtle.Turtle()
score_display.speed(0)
score_display.color("white")
score_display.penup()
score_display.hideturtle()
score_display.goto(0, 260)
score_display.write("Player A: 0 Player B: 0", align="center", font=("Courier", 24, "normal"))
# Function to update score
def update_score():
score_display.clear()
score_display.write(f"Player A: {score_a} Player B: {score_b}", align="center", font=("Courier", 24, "normal"))
# Paddle movement functions
def paddle_a_up():
y = paddle_a.ycor()
if y < 250:
paddle_a.sety(y + 20)
def paddle_a_down():
y = paddle_a.ycor()
if y > -250:
paddle_a.sety(y - 20)
def paddle_b_up():
y = paddle_b.ycor()
if y < 250:
paddle_b.sety(y + 20)
def paddle_b_down():
y = paddle_b.ycor()
if y > -250:
paddle_b.sety(y - 20)
# Keyboard bindings
wn.listen()
wn.onkeypress(paddle_a_up, "w")
wn.onkeypress(paddle_a_down, "s")
wn.onkeypress(paddle_b_up, "Up")
wn.onkeypress(paddle_b_down, "Down")
# Main game loop
while True:
wn.update()
# Move the ball
ball.setx(ball.xcor() + ball.dx)
ball.sety(ball.ycor() + ball.dy)
# Top and bottom wall collision
if ball.ycor() > 290:
ball.sety(290)
ball.dy *= -1
ball.dx *= speed_multiplier
ball.dy *= speed_multiplier
if ball.ycor() < -290:
ball.sety(-290)
ball.dy *= -1
ball.dx *= speed_multiplier
ball.dy *= speed_multiplier
# Right wall — Player A scores
if ball.xcor() > 390:
ball.goto(0, 0)
ball.dx = -initial_speed
ball.dy = initial_speed
score_a += 1
update_score()
# Left wall — Player B scores
if ball.xcor() < -390:
ball.goto(0, 0)
ball.dx = initial_speed
ball.dy = initial_speed
score_b += 1
update_score()
# Paddle collisions
if (340 < ball.xcor() < 350) and (paddle_b.ycor() - 50 < ball.ycor() < paddle_b.ycor() + 50):
ball.setx(340)
ball.dx *= -1
ball.dx *= speed_multiplier
ball.dy *= speed_multiplier
if (-350 < ball.xcor() < -340) and (paddle_a.ycor() - 50 < ball.ycor() < paddle_a.ycor() + 50):
ball.setx(-340)
ball.dx *= -1
ball.dx *= speed_multiplier
ball.dy *= speed_multiplier
Find quick answers to common questions about our lessons, pricing, scheduling, and how Exact Science can help your child excel.
Where do you hold your classes?
We hold our classes online or on-site on Saturdays at our branch in Pimlico Academy, London. You can find our timetable here.
What do you need to start learning online?
For lessons you only need a computer or phone with a microphone, camera and Internet access. Wherever you are - in London, Nottingham, New York or Bali - online lessons will be at hand.
When can I take the trial lesson?
You can get acquainted with the school at any time convenient for you. To do this, just leave a request and sign up for a lesson.
What should I expect from the trial lesson?
The trial lesson is a 30-minute online session designed to get a sense of how your child approaches mathematical thinking and problem solving. (In practice, it often runs a bit longer if the student is engaged!)
We typically explore a range of fun and challenging problems drawn from competitions. We adapt the difficulty based on how the student responds, aiming to make it both accessible and stimulating.
After the session, we’ll have a quick conversation with the parent to share observations and suggest a personalised path forward.
I can't attend class, what should I do?
It is OK, it happens! Students have the opportunity to cancel a lesson up to 8 hours before the scheduled time without loss of payment. So you can reschedule it for a convenient time, and the teacher will have the opportunity to
I don't have much free time, will I have time to study?
Learning can take place at your own pace. We will select a convenient schedule and at any time we will help you change the schedule, take a break or adjust the program.
How long is one lesson?
All classes last 1 hour.
Meet our team
Our teachers will tell you how to prepare for exams, help you cope with difficult tasks and win the Olympiad They will tell you about the pitfalls of exams and the most common mistakes, and explain how to avoid them
George Ionitsa
Founder & Maths and Coding Coach
What our students and parents say about learning with us
"Olympiad Maths Lessons helped me a lot to get the Gold medal in Junior Maths Challenge"
St. Paul's Student
"Thanks to the 'Data Science' and 'Coding in Python' lessons I got accepted to my dream university."