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
Subscribe to receive updates!
Be up-to-date with our recent updates, new problems and answers!
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
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 introductory 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.
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.
Hear from some of our amazing students who already achieved incredible results 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."
"Great courses, which thoroughly explained topics beyond the capability of the GCSE answer sheet. Thanks so much."
Ivan
GCSE Student in Dubai
"Financial Mathematics! Best course to understand Python and Mathematics behind Finance!"
Gleb
VC Investor
"We got silver in PMC! Thanks George!"
Mum of St. Paul's Student
Prepare for the Primary Maths Challenge
"My daughter took a batch of 10 classes with George to understand Python with Turtle. I found George extremely knowledgeable and accessible."
Dad of Latymer School Student
Python with Turtle
We’re hiring!
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