is one of the earliest and most iconic games in the history of digital entertainment. In its classic form, the game simulates a table tennis match with two paddles that move vertically across the screen to hit a bouncing ball. Each of the player controls a paddle and has to bounce the ball back to the other player, or else they give a point to the opposite player.
The history of the game is somewhat interesting. The Pong game was created and written by Allan Alcom as a test when he was recruited by Atari. This game then became a huge success, selling loads of machines across the world’s pubs and bars, and it so happened that the machines would choke with the loads of money people would put in, so that eventually the bars and pubs’ owners had to call Atari to fix their machines!
In this tutorial, we will use Python’s Object Oriented Programming approach to code the Pong game. This is an intermediate-level Python programming tutorial that requires one to have a preliminary knowledge of Python fundamentals: list, …
Understanding the Project
There are a number of ways we can code this game. We can use the straightforward method and do each task step by step with the necessary repetitions, or we can use Python’s Object Oriented Programming approach to escapre the repetition and have a neat and organized code. We will opt the second option as this would make the game’s program more systematic and less messy!
We will use Python’s Turtle module for the visual game development. The turtle module is a built-in functionality that allows one to visulalize code in an easy manner. It basically consists of a turtle that is drawing shapes and lines as it moves across the screen according to the coder’s instructions. It is a powerful tool to create beginner-level games, and get instant feedback through a visual screen.
The following are the key tasks that we will approach in an orderly manner:
- Creating the Game Screen – this is the screen on which the Pong game will be displayed
- Creating the Paddle & Paddle Class – this is the code that will create a paddle on screen, and configure its movements, which we will convert to a class as a blueprint to create 2 paddles, one on the left side and the other on the right side
- Creating the Ball Class and Objects – continuing with the OOP approach, we will create a generic ball class and then create the ball that will move across the screen, we will also define its relevant methods
- Detecting Collision of Ball with Top/Bottom Wall -this is the piece of code that will detect collision with the upper and lower walls, and if collision occurs, it will make the ball bounce across the y-axis
- Detecting Collision with Paddle – this is the piece of code that will detect whether the ball collides with the paddle. If yes, it will make the ball bounce; else, if the paddles misses the ball, it will give a score to the opposite player and restart the game with the ball at the centre.
- Creating the Scoreboard Class and Object – this is the piece of code that includes the creation of the Scoreboard class in a separate Python file and the creation of its object in the main game file.
Creating the Game Screen
The first task is to create the game screen. This screen will be rectangular in shape, as in the real game. We will first import the turtle module in or code and use its Screen class to create the screen object and customize it to have a width of 800px and a height of 600px using the Screen class setup() method. We will set the background color to black using the bgcolor() method, and name the screen as “Pong Game” using the title() method. Below is the code, where we have created the screen object:
from turtle import Turtle, Screen
#Setting up the Game Screen
screen = Screen()
screen.setup(width=800, height=600)
screen.bgcolor("black")
screen.title("Pong Game")
screen.exitonclick()
Notice that we have written the last line where we have used the screen’s exitonclick() method so as to ensure the screen will remain there until we click on it.
If you find any confusion in the above methods, feel free to check out the official documentation of the Turtle Module from here.
Following is the output as we run the program:

Creating the Paddle & Paddle Class
The next task is to create a paddle, which is a rectangular-shaped object at both sides of the Game Screen. We will create this paddle using the turtle module’s shape() function, and customize it to be white in color using the color() method, and use the shapesize() method to customise it to have a width of 20px and a height of 100px. Notice that we have passed 5 and 1 as the arguments to the shapesize() method. This is because the shapesize() is not in pixels, but in reference to a base of 20px. So to get a length of 100px, we will pass 5 (as 20px x 5 = 100px). Moreover, we will position it such that at the beginning of the game it is in the middle of the right side, that is, a y coordinate of 0 and an x coordinate of 350 (remember our screen is 800px wide). We will use the penup() method to remove the turtle’s trace and make it move to the desired location using the goto() method.
#Creating the Paddle
paddle = Turtle()
paddle.shape("square")
paddle.color("white")
paddle.shapesize(5,1)
paddle.penup()
paddle.goto(350,0)
The following is the output of the above code. We can see a paddle created on the Game Screen at the right side, without any turtle trace.

Running the above code will create the paddle. However, we can see that the paddle is first created, and then it goes to its location. In order to turn off the animation, we will add the screen’s class tracer() method in our code. This will also require us to update the screen manually:
#Retain the Original Code
screen.tracer(0)
screen.update()
screen.exitonclick()
Calling the tracer() method and passing it a value of 0 will turn off the animation.
Once we have created the paddle and updated the screen by turning off the animations, next is to configure the paddle movements. To do this, we will use screen listeners. The screen’s class listen() method allows us to listen to keyboard events, and the onkey() method allows us to call a defined function whenever a particular key is pressed. We will thus define the go_up and go_down functions that will make the paddle move up and down along the y-axis.
def go_up():
new_y = paddle.ycor() + 40
paddle.goto(paddle.xcor(), new_y)
def go_down():
new_y = paddle.ycor() - 40
paddle.goto(paddle.xcor(),new_y)
As can be seen, we have defined the paddle’s up and down movement function by making it move 40px vertically from its original position. Next, we will use the screen listeners capability to allow these functions to be called on pressing keyboard keys.
screen.listen()
screen.onkey(paddle.go_up, "Up")
screen.onkey(paddle.go_down, "Down")

Now that we have created the paddle and configured the mechanism of its movement, let us now shift our code to Object Oriented Programming Approach. This is because we will need 2 paddles for the game, and having a generic blueprint that creates paddles instantly will make our task easier. We will refactor our code to create another paddle easily. We will move all the paddle related code to another file and create the padlle class in it.
Since the paddles we are creating are in essence turtle objects, we will make this paddle class inherit from the Turtle class. So we will create a new python file in our PyCharm IDE and again import the turtle module’s Turtle class in this separate Python file. Next, we will use the class creation syntax and def __inti__() to define the Paddle class. As both the left and right paddles will have different positions across the game screen, we will add the x and y coordinates as attributes to the class.
Now we will use the concept of inheritance in OOP and make the Turtle class the super class, and the paddle class will inherit its attributes and methods. Next, we will just replace the word “paddle” in our former code where we created the paddle with the “self” keyword.
from turtle import Turtle, Screen
class Paddle(Turtle):
def __init__(self,x,y):
# Creating the Paddle Objects
super().__init__()
self.shape("square")
self.color("white")
self.shapesize(5, 1)
self.penup()
self.x = x
self.y = y
self.goto(x,y)
# Configure Paddle Movement
def go_up(self):
new_y = self.ycor() + 40
self.goto(self.xcor(), new_y)
def go_down(self):
new_y = self.ycor() - 40
self.goto(self.xcor(),new_y)
As can be seen above, we have also defined the two methods of Paddle class. One is the upward movement and the second is the downward movement that we have already defined earlier. Once the Paddle class is defined, we will create the paddle objects and configure the up and down movements of both paddles:
from paddle import Paddle
# Creating Paddle Objects
left_paddle = Paddle(-350, 0)
right_paddle = Paddle(350, 0)
# Configuring Paddles' Movement
screen.listen()
screen.onkey(right_paddle.go_up, "Up")
screen.onkey(right_paddle.go_down, "Down")
screen.onkey(left_paddle.go_up, "w")
screen.onkey(left_paddle.go_down, "s")
Running the Game
In order to run the game and update it using the Screen’s update() method, we will define a while loop that will continue to run until externally stopped, or when the condition of the loop turns to False.
#Game is ON:
game_is_on = True
while game_is_on:
screen.update()
Now, when you run the main file, you will see the game screen and paddles created, and the ability of the paddles to move.
Create the Ball Class & Objects
Now continuing on our OOP approach to code this game, we will create the Ball class as the generic blueprint and create the ball object from it in our main Python file. We will create the ball as a turtle object, by making the Ball class inherit from the super class Turtle. We will use the turtle class’s methods color() and shape() to initialize a ball of white color in a circular shape. As before, we will use the penup() method of turtle to hide the turtle’s trace.
from turtle import Turtle
class Ball(Turtle):
def __init__(self):
super().__init__()
self.color("white")
self.shape("circle")
self.penup()
Now that our ball’s attributes are defined, we will also create the ball’s methods of moving as soon as the game starts. The game will start with the ball being at the centre of the game screen, and when the screen refreshes, it will be moving in the right direction first. In our main while loop we will call this method so the ball will continue to move throughout when the game is on, that is, its x and y coordinates will change at every refresh of the game screen.
The way to make the ball move is by changing both its x and y coordinates by a certain number, let us say 10 for the time being. We will define the move() method of the ball and code the above scenario:
class Ball(Turtle):
#Retain previous code
def move(self):
new_x = self.xcor() + 10
new_y = self.ycor() + 10
self.goto(new_x, new_y)
We will add this method of the ball object to be called inside the game’s while loop:
#Game is ON:
game_is_on = True
while game_is_on:
screen.update()
ball.move()
On running the code, we see that the ball vanishes quickly, and what we are left with is just the 2 paddles.

We can resume the animation by commenting out the screen.tracer() lines and rerunning the code. We will now see the 2 paddles and the ball being created and moved.

Another way to visualise this is using the time module and bringing a delay in the main while loop of the game. This can be done as follows (without commenting out the tracer() function):
import time
#Retain the Original Code
#Game is ON:
game_is_on = True
while game_is_on:
time.sleep(0.1)
screen.update()
ball.move()
Now you can see that the ball moves at a slower pace and we can catch it with a paddle.
Detecting Collision of Ball with Top/Bottom Wall
Now that our ball is created and running, we need to design a mechanism to make the ball bounce when it hits the top and bottom walls, as for the left and right walls, the ball should be caught by the left and right paddles. If the ball is not caught, it would mean the other player scores a point.
So, considering that our ball is moving from the centre of the screen to the top right corner, and it reaches the corner, it needs to bounce now. In easy words, bouncing would simply be a change of direction in the y-axis, as the ball would still be going forward in the x-axis. We will now define a new method of the Ball class called bounce() and call it in the main game loop when the ball reaches the boundary:
from turtle import Turtle
class Ball(Turtle):
def __init__(self):
super().__init__()
self.color("white")
self.shape("circle")
self.penup()
self.x_move = 10
self.y_move = 10
def move(self):
new_x = self.xcor() + self.x_move
new_y = self.ycor() + self.y_move
self.goto(new_x, new_y)
def bounce(self):
self.y_move *= -1
Notice that in the above, we have defined 2 new attributes of the Ball class, the x_move and the y_move, and have made them equal to 10. Then, in the move() method, we have replaced the figure of 10 with these attributes. As can be seen, this comes in handy for our bounce() method. Now, whenever the ball bounces, it will move in the opposite direction to its previous y position. This simply means that if the ball is going up, and collides with the wall, the y_move would change from +10 to -10, and the ball will move downwards, as the negative number would mean the ball is moving down. Consequently, a collision with the bottom wall would change this y_move from -10 to +10, and the ball will then move upwards.
Now, let us add this condition in the main while loop:
while game_is_on:
#Retain Original Code
#Detect Collision with Top and Bottom Walls
if ball.ycor() > 275 or ball.ycor() < -275:
ball.bounce_y()
In the code above, we have added the condition of the collision with the walls to be detected, and then the bounce() method to be called. You can use any value for the boundaries, but through repeated tries, the value of 275 is good enough!

Detecting Collision with Paddle
Now that we know how to make the ball bounce from the top and bottom walls, the next step is to detect a collision with the paddle and make the ball bounce from the paddle. We will employ a similiar method as before, except that now we are talking about the x-axis.
The normal way to detect a collision between the ball and the wall is to use the distance method. If the distance between the two is less than a certain amount, we can conclude that the 2 have touched/collided. However, know that the distance() function works by calculating the distance between the centers of the two turtle objects. In our case, one is a 20x20px ball, and the other is a 20×200 rectangular paddle. The distance between them would vary along the length of the paddle. If the ball hits the paddle on its edge, the distance() method would fail to conclude that both of them have made contact.
We can add another condition which would check if the ball has gone past a certain point on the x-axis, over to the right (in the case of the right paddle), and it is within a 50px distance from the paddle, then the ball must have made contact. We will add this condition to the main while loop. Once the collision is detected, we will have the ball bounce, but this time in the x-direction. Let us redefine our bounce functions so we have both bounce functions, one for the x-axis when colliding with pthe addle, and the other on the y-axis when colliding with the wall:
def bounce_y(self):
self.y_move *= -1
def bounce_x(self):
self.x_move *= -1
while game_is_on:
...
# Detect Collision of the Ball with the Right Paddle
if ball.distance(right_paddle) < 50 and ball.xcor() > 320:
ball.bounce_x()
# Detect Collision of the Ball with the Left Paddle
elif ball.distance(left_paddle) < 50 and ball.xcor() < -320:
ball.bounce_x()
Note, we have added a value of 320 after some hit and trial and visualizations of the ball colliding with the paddle.

If one of the paddles misses the ball, then the other player gets a point, and the game restarts with the ball in the centre. In order to check if the ball is missed by the paddle, we can visualize this by considering the ball going beyond a certain point on the horizontal axis. We know that the width of the screen is 800 and the paddle is at 350 along the x-axis, so the paddle actually goes from 340 to 360 as it has a width of 20px, so if the ball goes beyond the 360 x axs, it means the paddles has missed the ball. This would mean we will reset the ball to the starting position at the centre value (0,0). We will define a reset_position() method of the ball that will be called when the above condition is met. Moreover, we will also add a feature that will reverse the ball’s direction, so instead of going to the right, it will go to the left.
Class Ball(Turtle):
...
def reset_position(self):
self.goto(0, 0)
self.bounce_x()
The bounce_x() method will cause the ball to reverse direction as it did when it would bounce off a paddle. Putting these conditions in the game’s main while loop:
while game_is_on:
...
# Detect Right Paddle Missing the Ball
if ball.xcor() > 380:
ball.reset_position()
# Detect Left Paddle Missing the Ball
if ball.xcor() < -380:
ball.reset_position()
Running the code above will show us what happens when a paddle misses the ball; the ball would reverse its direction and would go to the other padlle. Now all that’s left is to create a scoreboard to store and display the score for each player.
Creating the Scoreboard
In order to display and update the score for each player, we will define a scoreboard class in a new python file. We will create the Scoreboard class inheriting from the turtle class, and will define the attributes that will help the turtle object to write. First we will initialize the two attributes, l_score and r_score and set them to 0 at the beginning of the game. We will define two methods, l_point and r_point which will be called whenever a player misses the ball, and will increase the points of the other user. We will also define a method called update_scoreboard(), and call it when a player scores an additional point. This method, when called will simply update the scoreboard.
Following is the Scoreboard Class creation:
from turtle import Turtle
class Scoreboard(Turtle):
def __init__(self):
super().__init__()
self.color("white")
self.penup()
self.hideturtle()
self.l_score = 0
self.r_score = 0
self.update_scoreboard()
def update_scoreboard(self):
self.clear()
self.goto(-100, 200)
self.write(self.l_score, align="center", font=("Arial", 40, "normal"))
self.goto(100, 200)
self.write(self.r_score, align="center", font=("Arial", 40, "normal"))
def l_point(self):
self.l_score += 1
self.update_scoreboard()
def r_point(self):
self.r_score += 1
self.update_scoreboard()
The update_scoreboard() method creates a turtle that writes the score of both players on the main screen. Notice that we have used the Turtle module’s write() function in here.
Next we will import and create a scoreboard object in the main file, and we will use this object to access its methods, satisfying the two conditions: whenever a player’s paddle misses the ball, the other player would get a point.
from scoreboard import Scoreboard
#Initializing Scoreboard Object
scoreboard = Scoreboard()
while game_is_on:
...
# Detect Right Paddle Missing the Ball
if ball.xcor() > 380:
ball.reset_position()
scoreboard.l_point()
# Detect Left Paddle Missing the Ball
if ball.xcor() < -380:
ball.reset_position()
scoreboard.r_point()
This is where the game designing and coding comes to its end. Runing the main python file will generate the game screen and its components, with the ball moving as the game starts. Now you just need to fins a player to play this game with!
You can also change the speed of the game through some changes in the code (that’s for you to figure out!)
Conclusion
In this article, we have developed the classic Pong game with the help of the Python Turtle module. We have used the concept of Object Oriented Programming to create classes, initialize attributes and methods, and from these classes create objects in the main game file. This is an intermediate-level Python project, and if you stumbled upon some part of the code, make sure to either refer to the Python official documentation or revise your basic concepts, particularly OOP in this case.