You are currently viewing Pong Game With Python

Pong Game With Python

Introduction

Pong game is a classic arcade game that simulates table tennis. It was one of the earliest arcade video games, created by Atari and released in 1972. The game consists of two paddles (or “paddles”) and a ball, which moves between the two paddles. Players control one of the paddles, moving it up and down to hit the ball back and forth.The goal is to score points by making the ball pass the opponent’s paddle without being returned.

Now, let’s delve into why Python is a good choice for programming a pong game with python:

  1. Ease of Learning: Python is known for its simplicity and readability, making it an excellent choice for beginners. Its syntax is clear and concise, which means that even those new to programming can quickly understand and write code. Coding a pong game with python is an excellent choice by the way.

  2. Versatility: Python is a versatile language that supports both procedural and object-oriented programming paradigms. This flexibility allows developers to choose the approach that best suits their project’s needs. For a game like Pong, object-oriented programming (OOP) is particularly useful for organizing game entities like paddles, balls, and scores into classes.

  3. Extensive Libraries: Python has a vast ecosystem of libraries and frameworks, including Pygame, which is a set of Python modules designed for writing video games. Pygame provides functionality for handling graphics, sound, and input devices, making it an ideal choice for developing simple 2D games like Pong.

  4. Cross-Platform Compatibility: Python is a cross-platform language, meaning that Python code can run on various operating systems, including Windows, macOS, and Linux. This ensures that your Pong game can be played by users regardless of their platform.

  5. Community Support: Python has a large and active community of developers who contribute to its ecosystem by creating tutorials, documentation, and open-source projects. This means that if you encounter any issues while programming your pong game with python, you’re likely to find solutions and helpful resources online.

  6. Rapid Development: Python’s high-level nature and extensive standard library allow developers to build projects quickly. With Python, you can prototype and implement game features faster, enabling you to iterate on your Pong game more efficiently.

Overall, Python’s simplicity, versatility, rich ecosystem, and strong community support make it an excellent choice for programming a classic game like Pong. Whether you’re a beginner or an experienced developer, Python provides the tools and resources you need to create fun and engaging games.

Before beginning the explanation of the code, let’s check how collision works and understand more the concept of it before trying to implement an algorithm for it. When two objects collide in a game, we typically want to simulate the physics of their interaction. Here’s a simplified explanation of collision physics:

  1. Detecting Collision:

    • Before we can handle collision, we need to detect when it occurs. This often involves checking if the hitboxes or bounding boxes of the objects intersect.
  2. Handling Collision:

    • Once we detect a collision, we need to respond appropriately. There are several ways to handle collision:
      • Elastic Collision: Objects bounce off each other with energy conservation.
      • Inelastic Collision: Objects stick together after collision, losing some energy.
      • Collision Resolution: Objects push each other apart to resolve the overlap
  3. Collision Response:

    • After determining the collision, we update the objects’ velocities or positions to reflect the collision:
      • Velocity Changes: Depending on the type of collision, we adjust the velocities of the objects involved.
      • Position Changes: We may need to move the objects so they are no longer overlapping.
  4. Conservation of Momentum:

    • In physics, the total momentum of a closed system remains constant unless acted upon by an external force. In game collisions, we often apply this principle:
      • Before Collision: The total momentum of the system is calculated.
      • After Collision: The total momentum remains the same, but it may be distributed differently among the colliding objects.
  5. Calculating New Velocities:

    • In elastic collisions, we calculate the new velocities of the objects based on their masses and initial velocities. This is typically done using momentum and kinetic energy equations.
  6. Friction and Restitution:

    • In addition to simple collision, we may also consider effects like friction (slowing objects as they slide against each other) and restitution (bounciness of surfaces).

In Python, implementing collision physics involves writing code to:

  • Detect when objects collide.
  • Respond to the collision by updating object positions or velocities.
  • Consider factors like mass, velocity, and angle of collision to determine the outcome.

Using libraries like Pygame can simplify collision detection and response, as it provides built-in functions for handling collisions between sprites or rectangles.

If you are still very new to python, you can take a look the courses available here https://codingwithfad.com/category/python/

Algorithm Collision

def check_collision(rect1, rect2):
# Get the positions and sizes of the rectangles
x1, y1, w1, h1 = rect1
x2, y2, w2, h2 = rect2

# Check for overlap in the x-axis
if x1 + w1 > x2 and x1 < x2 + w2:
# Check for overlap in the y-axis
if y1 + h1 > y2 and y1 < y2 + h2:
return True # Collision detected
return False # No collision


# Example usage:
rect1 = (100, 100, 50, 50) # Rect1: (x, y, width, height)
rect2 = (200, 200, 50, 50) # Rect2: (x, y, width, height)

if check_collision(rect1, rect2):
print("Collision detected!")
else:
print("No collision.")

Here’s a basic collision detection algorithm between two rectangular objects in Python:

This algorithm checks if two rectangles overlap by comparing their positions and sizes along the x-axis and y-axis. If there is any overlap in both axes, a collision is detected. Otherwise, there’s no collision.

You can take a look at the plane game with python if you want to understand well collision handling: https://codingwithfad.com/create-a-plane-game-with-python-6/?ppwp=1

Initializing the Game

# Initialize Pygame
pygame.init() # Initialize Pygame

# Set up the screen
screen_width = 800 # Set the width of the screen
screen_height = 600 # Set the height of the screen
screen = pygame.display.set_mode((screen_width, screen_height)) # Create the game window
pygame.display.set_caption("Pong") # Set the title of the game window

Now let’s start the explanation of the full code. We start by initializing Pygame and setting up the game screen.

Explanation:

  • pygame.init(): Initializes all imported Pygame modules. It needs to be called before using any other Pygame functions.
  • screen_width = 800 and screen_height = 600: Define the width and height of the game window, respectively.
  • screen = pygame.display.set_mode((screen_width, screen_height)): Creates the game window with the specified dimensions using pygame.display.set_mode().
  • pygame.display.set_caption("Pong"): Sets the title of the game window to “Pong” using pygame.display.set_caption(). This is the text that appears on the title bar of the window.

Define colors and constants:

# Colors
WHITE = (255, 255, 255) # Define the color white
BLACK = (0, 0, 0) # Define the color black

# Paddle constants
PADDLE_WIDTH = 10 # Set the width of the paddle
PADDLE_HEIGHT = 100 # Set the height of the paddle
PADDLE_SPEED = 5 # Set the speed of the paddle

# Ball constants
BALL_SIZE = 10 # Set the size of the ball
BALL_SPEED_X = 5 # Set the horizontal speed of the ball
BALL_SPEED_Y = 5 # Set the vertical speed of the ball

We define colors using RGB values and constants for paddle and ball properties such as size and speed.

Explanation:

  • WHITE = (255, 255, 255): Defines the RGB value for white color.
  • BLACK = (0, 0, 0): Defines the RGB value for black color.
  • PADDLE_WIDTH = 10: Sets the width of the paddle to 10 pixels.
  • PADDLE_HEIGHT = 100: Sets the height of the paddle to 100 pixels.
  • PADDLE_SPEED = 5: Sets the speed of the paddle to 5 pixels per frame.
  • BALL_SIZE = 10: Sets the diameter of the ball to 10 pixels.
  • BALL_SPEED_X = 5: Sets the horizontal speed of the ball to 5 pixels per frame.
  • BALL_SPEED_Y = 5: Sets the vertical speed of the ball to 5 pixels per frame.

Define Paddle class:

# Define paddles
class Paddle: # Define a class for the paddles
def __init__(self, x, y): # Initialize the paddle object with position
self.rect = pygame.Rect(x, y, PADDLE_WIDTH, PADDLE_HEIGHT) # Create a rectangular paddle

def draw(self): # Method to draw the paddle
pygame.draw.rect(screen, WHITE, self.rect) # Draw the paddle on the screen

def move_up(self): # Method to move the paddle up
self.rect.y -= PADDLE_SPEED # Adjust the y-coordinate of the paddle

def move_down(self): # Method to move the paddle down
self.rect.y += PADDLE_SPEED # Adjust the y-coordinate of the paddle

We define a class Paddle to represent both the player’s paddle and the AI paddle. The class includes methods for drawing the paddle and moving it up or down.

Explanation:

  • Paddle class:
    • Defines a class named Paddle to represent the paddles in the game.
  • Initializer method:
    • Initializes the paddle object with the provided x and y coordinates.
  • self.rect:
    • Creates a rectangular paddle using pygame.Rect(), with its top-left corner positioned at (x, y) and dimensions of PADDLE_WIDTH (width) and PADDLE_HEIGHT (height).
  • Draw method:
    • Draws the paddle on the screen.
  • pygame.draw.rect(screen, WHITE, self.rect):
    • Draws a white rectangle representing the paddle on the game screen, using the rectangle defined by self.rect.
  • Move methods:
    • Moves the paddle vertically
  • self.rect.y -= PADDLE_SPEED (move_up):
    • Decreases the y-coordinate of the paddle by PADDLE_SPEED, moving it up.
  • self.rect.y += PADDLE_SPEED (move_down):
    • Increases the y-coordinate of the paddle by PADDLE_SPEED, moving it down.

Define Ball class:

We define a class Ball to represent the game ball. The class includes methods for drawing the ball, moving it, and checking for collisions with the paddles and screen boundaries.

# Define ball
class Ball: # Define a class for the ball
def __init__(self): # Initialize the ball object
self.rect = pygame.Rect(screen_width // 2 - BALL_SIZE // 2, screen_height // 2 - BALL_SIZE // 2, BALL_SIZE, BALL_SIZE) # Create a rectangular ball
self.direction_x = random.choice([-1, 1]) # Set the initial horizontal direction of the ball
self.direction_y = random.choice([-1, 1]) # Set the initial vertical direction of the ball

def draw(self): # Method to draw the ball
pygame.draw.rect(screen, WHITE, self.rect) # Draw the ball on the screen

def move(self): # Method to move the ball
self.rect.x += self.direction_x * BALL_SPEED_X # Move the ball horizontally
self.rect.y += self.direction_y * BALL_SPEED_Y # Move the ball vertically

def check_collision(self): # Method to check for collisions
if self.rect.colliderect(player_paddle.rect) or self.rect.colliderect(ai_paddle.rect): # Check collision with paddles
self.direction_x *= -1 # Reverse the horizontal direction of the ball

if self.rect.top <= 0 or self.rect.bottom >= screen_height: # Check collision with top or bottom of the screen
self.direction_y *= -1 # Reverse the vertical direction of the ball

Explanation:

  • WHITE = (255, 255, 255): Defines the RGB value for white color.
  • BLACK = (0, 0, 0): Defines the RGB value for black color.
  • PADDLE_WIDTH = 10: Sets the width of the paddle to 10 pixels.
  • PADDLE_HEIGHT = 100: Sets the height of the paddle to 100 pixels.
  • PADDLE_SPEED = 5: Sets the speed of the paddle to 5 pixels per frame.
  • BALL_SIZE = 10: Sets the diameter of the ball to 10 pixels.
  • BALL_SPEED_X = 5: Sets the horizontal speed of the ball to 5 pixels per frame.
  • BALL_SPEED_Y = 5: Sets the vertical speed of the ball to 5 pixels per frame.

Create paddles, ball, and main game loop: We create instances of the Paddle and Ball classes. Inside the main game loop, we handle events, update paddle and ball positions, check for collisions, draw everything on the screen, and update the display.

# Create paddles
player_paddle = Paddle(20, screen_height // 2 - PADDLE_HEIGHT // 2) # Create the player's paddle
ai_paddle = Paddle(screen_width - 30, screen_height // 2 - PADDLE_HEIGHT // 2) # Create the AI's paddle

# Create ball
ball = Ball() # Create the ball

# Main game loop
running = True # Flag to control the main game loop
while running: # Main game loop
for event in pygame.event.get(): # Loop through all events
if event.type == pygame.QUIT: # Check if the user clicked the close button
running = False # Set the running flag to False to exit the loop

keys = pygame.key.get_pressed() # Get all pressed keys
if keys[pygame.K_UP] and player_paddle.rect.top > 0: # Check if the Up arrow key is pressed and the paddle is not at the top edge
player_paddle.move_up() # Move the player's paddle up
if keys[pygame.K_DOWN] and player_paddle.rect.bottom < screen_height: # Check if the Down arrow key is pressed and the paddle is not at the bottom edge
player_paddle.move_down() # Move the player's paddle down

# AI Paddle movement
if ball.rect.centery < ai_paddle.rect.centery: # If the ball is above the AI paddle
ai_paddle.move_up() # Move the AI paddle up
elif ball.rect.centery > ai_paddle.rect.centery: # If the ball is below the AI paddle
ai_paddle.move_down() # Move the AI paddle down

# Move ball
ball.move() # Move the ball

# Check for collisions
ball.check_collision() # Check for collisions

# Fill screen with black color
screen.fill(BLACK) # Fill the screen with black color

# Draw paddles and ball
player_paddle.draw() # Draw the player's paddle
ai_paddle.draw() # Draw the AI's paddle
ball.draw() # Draw the ball

# Update display
pygame.display.flip() # Update the display

# Cap the frame rate
pygame.time.Clock().tick(60) # Limit the frame rate to 60 frames per second

# Quit Pygame
pygame.quit() # Quit Pygame

Explanation:

  • player_paddle = Paddle(20, screen_height // 2 - PADDLE_HEIGHT // 2): Creates the player’s paddle at a fixed position on the left side of the screen.
  • ai_paddle = Paddle(screen_width - 30, screen_height // 2 - PADDLE_HEIGHT // 2): Creates the AI’s paddle at a fixed position on the right side of the screen.
  • The main game loop:
    • Checks for events such as quitting the game.
    • Moves the player’s paddle up or down based on key presses.
    • Moves the AI paddle to follow the ball.
    • Moves the ball, checks for collisions, and updates the positions.
    • Clears the screen and draws the paddles and ball.
    • Updates the display and caps the frame rate to control the game speed.
  • The game loop continues until the player quits the game.

Add Scores
We can add scoring into the screen to make the game more appealing. The process is very simple and allow us to keep tracking the score on each part of the screen.

# Initialize scores
player_score = 0 # Initialize player's score to zero
ai_score = 0 # Initialize AI's score to zero

# Function to display scores
def display_scores():
font = pygame.font.Font(None, 36) # Create a font object with size 36
player_text = font.render("Player: " + str(player_score), True, WHITE) # Render player's score text
ai_text = font.render("AI: " + str(ai_score), True, WHITE) # Render AI's score text
screen.blit(player_text, (20, 20)) # Display player's score on the screen at position (20, 20)
screen.blit(ai_text, (screen_width - 120, 20)) # Display AI's score on the screen at a calculated position

Optimize Collision Detection

We can optimize collision detection by using Pygame’s built-in collision functions, such as pygame.sprite.spritecollide().

# Check for collisions
if pygame.sprite.spritecollide(ball, [player_paddle, ai_paddle], False):
ball.direction_x *= -1

if ball.rect.top <= 0 or ball.rect.bottom >= screen_height:
ball.direction_y *= -1

Pong Game with Python (Full Code)

Here’s the complete code of the Pong game with Python

import pygame
import random

# Initialize Pygame
pygame.init()

# Set up the screen
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Pong")

# Colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)

# Paddle constants
PADDLE_WIDTH = 10
PADDLE_HEIGHT = 100
PADDLE_SPEED = 5

# Ball constants
BALL_SIZE = 10
BALL_SPEED_X = 5
BALL_SPEED_Y = 5

# Initialize scores
player_score = 0
ai_score = 0

# Define paddles
class Paddle:
def __init__(self, x, y):
self.rect = pygame.Rect(x, y, PADDLE_WIDTH, PADDLE_HEIGHT)

def draw(self):
pygame.draw.rect(screen, WHITE, self.rect)

def move_up(self):
self.rect.y -= PADDLE_SPEED

def move_down(self):
self.rect.y += PADDLE_SPEED

# Define ball
class Ball:
def __init__(self):
self.rect = pygame.Rect(screen_width // 2 - BALL_SIZE // 2, screen_height // 2 - BALL_SIZE // 2, BALL_SIZE, BALL_SIZE)
self.direction_x = random.choice([-1, 1])
self.direction_y = random.choice([-1, 1])

def draw(self):
pygame.draw.rect(screen, WHITE, self.rect)

def move(self):
self.rect.x += self.direction_x * BALL_SPEED_X
self.rect.y += self.direction_y * BALL_SPEED_Y

def check_collision(self):
if self.rect.colliderect(player_paddle.rect) or self.rect.colliderect(ai_paddle.rect):
self.direction_x *= -1

if self.rect.top <= 0 or self.rect.bottom >= screen_height:
self.direction_y *= -1

# If ball goes past the paddles
if self.rect.left <= 0:
# Increment AI's score
global ai_score
ai_score += 1
# Reset ball position
self.rect.x = screen_width // 2 - BALL_SIZE // 2
self.rect.y = screen_height // 2 - BALL_SIZE // 2
# Reset ball direction
self.direction_x = random.choice([-1, 1])
self.direction_y = random.choice([-1, 1])
elif self.rect.right >= screen_width:
# Increment player's score
global player_score
player_score += 1
# Reset ball position
self.rect.x = screen_width // 2 - BALL_SIZE // 2
self.rect.y = screen_height // 2 - BALL_SIZE // 2
# Reset ball direction
self.direction_x = random.choice([-1, 1])
self.direction_y = random.choice([-1, 1])

# Create paddles
player_paddle = Paddle(20, screen_height // 2 - PADDLE_HEIGHT // 2)
ai_paddle = Paddle(screen_width - 30, screen_height // 2 - PADDLE_HEIGHT // 2)

# Create ball
ball = Ball()

# Main game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False

keys = pygame.key.get_pressed()
if keys[pygame.K_UP] and player_paddle.rect.top > 0:
player_paddle.move_up()
if keys[pygame.K_DOWN] and player_paddle.rect.bottom < screen_height:
player_paddle.move_down()

# AI Paddle movement
if ball.rect.centery < ai_paddle.rect.centery:
ai_paddle.move_up()
elif ball.rect.centery > ai_paddle.rect.centery:
ai_paddle.move_down()

# Move ball
ball.move()

# Check for collisions
ball.check_collision()

# Fill screen with black color
screen.fill(BLACK)

# Draw paddles and ball
player_paddle.draw()
ai_paddle.draw()
ball.draw()

# Display scores
font = pygame.font.Font(None, 36)
player_text = font.render("Player: " + str(player_score), True, WHITE)
ai_text = font.render("AI: " + str(ai_score), True, WHITE)
screen.blit(player_text, (20, 20))
screen.blit(ai_text, (screen_width - 120, 20))

# Update display
pygame.display.flip()

# Cap the frame rate
pygame.time.Clock().tick(60)

# Quit Pygame
pygame.quit()

Conclusion

We have successfully developed a classic Pong game using Python. Throughout the development process, we implemented various features to enhance gameplay and user experience.

We started by setting up the game window and defining the game’s colors, paddles, and ball properties. The game includes two paddles controlled by the player and an AI opponent. The ball moves dynamically across the screen, bouncing off walls and paddles.

To make the game more engaging, we added a scoring system that keeps track of points for both the player and the AI. The scores are displayed on the screen, allowing players to monitor their progress.

Furthermore, we improved the AI paddle’s behavior, making it more responsive to the ball’s movements. This enhancement adds a level of challenge, making the game more enjoyable for players.

Lastly, we created a main menu function to provide players with a smooth entry into the game. The menu offers clear instructions and prompts the player to start the game with a press of the space bar.

Overall, our Pong game provides a fun and nostalgic gaming experience. Players can enjoy challenging gameplay, compete for high scores, and relive the excitement of this classic arcade game.

Leave a Reply