Lesson 5 of 8

Build Your Own Pong Game!

Create the classic arcade game with paddles, ball, and scoring

Learning Objectives

  • Create player-controlled paddles using keyboard input
  • Program ball physics and collision detection
  • Add scoring system and game reset functionality
  • Build a complete playable game from scratch

What is Pong?

Pong is one of the first video games ever made! It's like table tennis - two players control paddles to hit a ball back and forth. The goal is to make your opponent miss the ball.

🏓 Left Paddle

Player 1 uses W and S keys

⚽ Ball

Bounces around the screen

🏓 Right Paddle

Player 2 uses UP and DOWN arrows

Step 1: Game Setup

Let's start by importing the libraries we need and setting up our game window:

from tkinter import *
import random
import time

# Create the main game window
tk = Tk()
tk.title("Pong Game - Arrow Keys: Move | Space: Restart")
tk.resizable(0, 0)
tk.wm_attributes("-topmost", 1)
canvas = Canvas(tk, width=500, height=400, bd=0, highlightthickness=0)
canvas.pack()

# Make sure the window can receive keyboard input
canvas.focus_set()
tk.update()

Step 2: Creating the Ball Class

Let's create a Ball class that handles the ball's movement and collision detection:

class Ball:
    def __init__(self, canvas, paddle, color):
        self.canvas = canvas
        self.paddle = paddle
        self.id = canvas.create_oval(10, 10, 25, 25, fill=color)
        self.canvas.move(self.id, 245, 100)
        starts = [-3, -2, -1, 1, 2, 3]
        random.shuffle(starts)
        self.x = starts[0]
        self.y = -3
        self.canvas_height = self.canvas.winfo_height()
        self.canvas_width = self.canvas.winfo_width()
        self.hit_bottom = False
        self.score = 0

Step 3: Creating the Paddle Class

Now let's create the Paddle class that handles player controls:

Control Scheme

Arrow Keys:
← = Move Left
→ = Move Right
Game Control:
Spacebar = Restart Game
class Paddle:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_rectangle(0, 0, 100, 10, fill=color)
        self.canvas.move(self.id, 200, 300)
        self.x = 0
        self.canvas_width = self.canvas.winfo_width()
        self.left_pressed = False
        self.right_pressed = False
        
        # Bind key press and release events
        self.canvas.bind_all('<KeyPress-Left>', self.left_down)
        self.canvas.bind_all('<KeyRelease-Left>', self.left_up)
        self.canvas.bind_all('<KeyPress-Right>', self.right_down)
        self.canvas.bind_all('<KeyRelease-Right>', self.right_up)

Complete Pong Game - Enhanced Version!

Enhanced Pong with Scoring & Restart!

Here's our improved Pong game with scoring, game over screen, and restart functionality! Copy this into Spyder and run it to play the enhanced version.

Game Features

  • Arrow Keys: Move the paddle left and right
  • Live Score: See your score update in real-time
  • Game Over Screen: Shows final score when you miss
  • Spacebar: Restart the game instantly
  • Smooth Controls: Responsive paddle movement
from tkinter import *
import random
import time

class Ball:
    def __init__(self, canvas, paddle, color):
        self.canvas = canvas
        self.paddle = paddle
        self.id = canvas.create_oval(10, 10, 25, 25, fill=color)
        self.canvas.move(self.id, 245, 100)
        starts = [-3, -2, -1, 1, 2, 3]
        random.shuffle(starts)
        self.x = starts[0]
        self.y = -3
        self.canvas_height = self.canvas.winfo_height()
        self.canvas_width = self.canvas.winfo_width()
        self.hit_bottom = False
        self.score = 0
    
    def hit_paddle(self, pos):
        paddle_pos = self.canvas.coords(self.paddle.id)
        if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:
            if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]:
                return True
        return False
    
    def draw(self):
        self.canvas.move(self.id, self.x, self.y)
        pos = self.canvas.coords(self.id)
        
        # Ball hits top of screen
        if pos[1] <= 0:
            self.y = 3
        
        # Ball hits bottom of screen
        if pos[3] >= self.canvas_height:
            self.hit_bottom = True
        
        # Ball hits paddle
        if self.hit_paddle(pos) == True:
            self.y = -3
            self.score += 1
        
        # Ball hits left side
        if pos[0] <= 0:
            self.x = 3
        
        # Ball hits right side
        if pos[2] >= self.canvas_width:
            self.x = -3
    
    def reset(self):
        """Reset ball to starting position"""
        self.canvas.coords(self.id, 10, 10, 25, 25)
        self.canvas.move(self.id, 245, 100)
        starts = [-3, -2, -1, 1, 2, 3]
        random.shuffle(starts)
        self.x = starts[0]
        self.y = -3
        self.hit_bottom = False
        self.score = 0

class Paddle:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_rectangle(0, 0, 100, 10, fill=color)
        self.canvas.move(self.id, 200, 300)
        self.x = 0
        self.canvas_width = self.canvas.winfo_width()
        self.left_pressed = False
        self.right_pressed = False
        
        # Bind key press and release events
        self.canvas.bind_all('<KeyPress-Left>', self.left_down)
        self.canvas.bind_all('<KeyRelease-Left>', self.left_up)
        self.canvas.bind_all('<KeyPress-Right>', self.right_down)
        self.canvas.bind_all('<KeyRelease-Right>', self.right_up)
        self.canvas.bind_all('<KeyPress-space>', self.restart_game)
        
        # Store reference to ball for restart functionality
        self.ball = None
    
    def draw(self):
        # Update movement based on key states
        if self.left_pressed:
            self.x = -3
        elif self.right_pressed:
            self.x = 3
        else:
            self.x = 0
            
        self.canvas.move(self.id, self.x, 0)
        pos = self.canvas.coords(self.id)
        
        # Keep paddle on screen
        if pos[0] <= 0:
            self.canvas.move(self.id, -pos[0], 0)
        elif pos[2] >= self.canvas_width:
            self.canvas.move(self.id, self.canvas_width - pos[2], 0)
    
    def left_down(self, evt):
        self.left_pressed = True
    
    def left_up(self, evt):
        self.left_pressed = False
    
    def right_down(self, evt):
        self.right_pressed = True
    
    def right_up(self, evt):
        self.right_pressed = False
    
    def restart_game(self, evt):
        if self.ball and self.ball.hit_bottom:
            self.ball.reset()

# Create the main game window
tk = Tk()
tk.title("Pong Game - Arrow Keys: Move | Space: Restart")
tk.resizable(0, 0)
tk.wm_attributes("-topmost", 1)
canvas = Canvas(tk, width=500, height=400, bd=0, highlightthickness=0)
canvas.pack()

# Make sure the window can receive keyboard input
canvas.focus_set()
tk.update()

# Create paddle and ball
paddle = Paddle(canvas, 'blue')
ball = Ball(canvas, paddle, 'red')

# Link paddle to ball for restart functionality
paddle.ball = ball

# Create score display
score_text = canvas.create_text(50, 20, text="Score: 0", fill="black", font=("Arial", 16))
game_over_text = None

# Game loop
while 1:
    if ball.hit_bottom == False:
        ball.draw()
        paddle.draw()
        
        # Update score display
        canvas.itemconfig(score_text, text="Score: " + str(ball.score))
        
        # Remove game over text if it exists
        if game_over_text:
            canvas.delete(game_over_text)
            game_over_text = None
    else:
        # Game over - show message
        if not game_over_text:
            game_over_text = canvas.create_text(250, 200, 
                text="GAME OVER!\nFinal Score: " + str(ball.score) + "\nPress SPACE to restart", 
                fill="red", font=("Arial", 20), justify="center")
    
    tk.update_idletasks()
    tk.update()
    time.sleep(0.01)

Fun Challenges

Easy Challenges

  • • Change the ball and paddle colors
  • • Make the ball move faster
  • • Add sound effects when ball hits paddle
  • • Change the background color

Hard Challenges

  • • Add a "Game Over" screen at 5 points
  • • Make the ball speed up after each hit
  • • Add power-ups that appear randomly
  • • Create an AI opponent