Of course! Creating a Pac-Man game in Python is a fantastic project for learning game development concepts. It involves handling player input, game state, collision detection, and rendering graphics.

I'll guide you through the process, starting with the simplest possible version and then building up to a more complete game. We'll use the Pygame library, which is the standard for 2D games in Python.
Option 1: The "Hello, World" of Pac-Man (A Very Simple Version)
This version will have a yellow circle that you can move around a maze, collecting dots. It's the absolute minimum to get something working.
Step 1: Install Pygame
If you don't have it installed, open your terminal or command prompt and run:
pip install pygame
Step 2: The Basic Code
Create a file named simple_pacman.py and paste this code in.

import pygame
import sys
# 1. Initialize Pygame
pygame.init()
# 2. Set up the screen
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Simple Pac-Man")
# 3. Define colors
BLACK = (0, 0, 0)
YELLOW = (255, 255, 0)
WHITE = (255, 255, 255)
# 4. Create the Pac-Man
PACMAN_SIZE = 30
pacman_x = SCREEN_WIDTH // 2
pacman_y = SCREEN_HEIGHT // 2
pacman_speed = 5
# 5. Create the dots (pellets)
dots = []
for x in range(50, SCREEN_WIDTH - 50, 50):
for y in range(50, SCREEN_HEIGHT - 50, 50):
dots.append([x, y])
# 6. Game loop
clock = pygame.time.Clock()
running = True
while running:
# Event handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Get keyboard input for continuous movement
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
pacman_x -= pacman_speed
if keys[pygame.K_RIGHT]:
pacman_x += pacman_speed
if keys[pygame.K_UP]:
pacman_y -= pacman_speed
if keys[pygame.K_DOWN]:
pacman_y += pacman_speed
# Keep Pac-Man on the screen
pacman_x = max(PACMAN_SIZE, min(SCREEN_WIDTH - PACMAN_SIZE, pacman_x))
pacman_y = max(PACMAN_SIZE, min(SCREEN_HEIGHT - PACMAN_SIZE, pacman_y))
# Drawing
screen.fill(BLACK)
# Draw Pac-Man
pygame.draw.circle(screen, YELLOW, (pacman_x, pacman_y), PACMAN_SIZE)
# Draw dots
for dot in dots:
pygame.draw.circle(screen, WHITE, dot, 5)
# Check for dot collection
for dot in dots[:]: # Iterate over a copy of the list
distance = ((pacman_x - dot[0])**2 + (pacman_y - dot[1])**2)**0.5
if distance < PACMAN_SIZE:
dots.remove(dot)
# Update the display
pygame.display.flip()
# Cap the frame rate
clock.tick(60)
# Quit Pygame
pygame.quit()
sys.exit()
How to Run It
Save the file and run it from your terminal:
python simple_pacman.py
You'll see a yellow circle (Pac-Man) that you can move with the arrow keys, and it will erase the white dots as it touches them.
Option 2: A More Complete Pac-Man Game
This version includes:
- A proper maze layout.
- Ghosts that move randomly.
- A score counter.
- Game over conditions.
This requires a bit more code, but it's much closer to the real game.

Step 1: Create the Maze
We'll represent the maze as a 2D list (a grid). 1 will be a wall, and 0 will be a path.
# Maze layout (1 = wall, 0 = path, 2 = dot)
# This is a simple maze. You can design your own!
MAZE = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1],
[1, 2, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 2, 1],
[1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1],
[1, 2, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 2, 1],
[1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1],
[1, 1, 1, 2, 1, 2, 1, 1, 1, 2, 1, 2, 1, 1, 1],
[1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1],
[1, 2, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 2, 1],
[1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]
CELL_SIZE = 40
MAZE_WIDTH = len(MAZE[0])
MAZE_HEIGHT = len(MAZE)
SCREEN_WIDTH = MAZE_WIDTH * CELL_SIZE
SCREEN_HEIGHT = MAZE_HEIGHT * CELL_SIZE
Step 2: The Full Code
Create a file named pacman_game.py and use this code. It's heavily commented to explain each part.
import pygame
import sys
import random
# --- Constants ---
# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
BLUE = (0, 0, 255)
RED = (255, 0, 0)
# Game settings
CELL_SIZE = 40
FPS = 10 # Slower for a classic feel
# Maze layout (1 = wall, 0 = path, 2 = dot)
MAZE = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1],
[1, 2, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 2, 1],
[1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1],
[1, 2, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 2, 1],
[1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1],
[1, 1, 1, 2, 1, 2, 1, 1, 1, 2, 1, 2, 1, 1, 1],
[1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1],
[1, 2, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 2, 1],
[1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]
# --- Initialize Pygame ---
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Pac-Man Game")
clock = pygame.time.Clock()
font = pygame.font.SysFont('Arial', 20)
# --- Game State Variables ---
score = 0
game_over = False
# --- Helper Functions ---
def load_maze():
"""Creates the maze and dot positions from the MAZE constant."""
dots = []
for y, row in enumerate(MAZE):
for x, cell in enumerate(row):
if cell == 2:
dots.append([x * CELL_SIZE + CELL_SIZE // 2, y * CELL_SIZE + CELL_SIZE // 2])
return dots
def is_valid_move(new_x, new_y):
"""Checks if the new position is not a wall."""
grid_x = new_x // CELL_SIZE
grid_y = new_y // CELL_SIZE
if 0 <= grid_x < MAZE_WIDTH and 0 <= grid_y < MAZE_HEIGHT:
return MAZE[grid_y][grid_x] != 1
return False
# --- Game Objects ---
class Pacman:
def __init__(self, x, y):
self.x = x
self.y = y
self.speed = CELL_SIZE
self.direction = None
self.next_direction = None
def update(self):
# Try to change direction if a key was pressed
if self.next_direction:
next_x, next_y = self.get_next_position(self.next_direction)
if is_valid_move(next_x, next_y):
self.direction = self.next_direction
self.next_direction = None
# Move in the current direction
if self.direction:
next_x, next_y = self.get_next_position(self.direction)
if is_valid_move(next_x, next_y):
self.x, self.y = next_x, next_y
def get_next_position(self, direction):
"""Calculates the next position based on direction."""
if direction == "UP":
return self.x, self.y - self.speed
if direction == "DOWN":
return self.x, self.y + self.speed
if direction == "LEFT":
return self.x - self.speed, self.y
if direction == "RIGHT":
return self.x + self.speed, self.y
def draw(self, screen):
pygame.draw.circle(screen, YELLOW, (self.x, self.y), CELL_SIZE // 2 - 2)
class Ghost:
def __init__(self, x, y, color):
self.x = x
self.y = y
self.color = color
self.speed = CELL_SIZE // 2
self.direction = random.choice(["UP", "DOWN", "LEFT", "RIGHT"])
def update(self):
# Simple AI: Try to move in the current direction, if not, pick a new one
next_x, next_y = self.get_next_position(self.direction)
if is_valid_move(next_x, next_y):
self.x, self.y = next_x, next_y
else:
self.direction = random.choice(["UP", "DOWN", "LEFT", "RIGHT"])
# Try the new direction
next_x, next_y = self.get_next_position(self.direction)
if is_valid_move(next_x, next_y):
self.x, self.y = next_x, next_y
def get_next_position(self, direction):
if direction == "UP":
return self.x, self.y - self.speed
if direction == "DOWN":
return self.x, self.y + self.speed
if direction == "LEFT":
return self.x - self.speed, self.y
if direction == "RIGHT":
return self.x + self.speed, self.y
def draw(self, screen):
pygame.draw.circle(screen, self.color, (self.x, self.y), CELL_SIZE // 2 - 2)
# --- Create Game Objects ---
# Find a starting position for Pac-Man (a path cell)
start_x, start_y = 0, 0
for y, row in enumerate(MAZE):
for x, cell in enumerate(row):
if cell == 0:
start_x, start_y = x * CELL_SIZE + CELL_SIZE // 2, y * CELL_SIZE + CELL_SIZE // 2
break
if start_x != 0:
break
pacman = Pacman(start_x, start_y)
ghosts = [
Ghost(7 * CELL_SIZE + CELL_SIZE // 2, 5 * CELL_SIZE + CELL_SIZE // 2, RED),
Ghost(7 * CELL_SIZE + CELL_SIZE // 2, 5 * CELL_SIZE + CELL_SIZE // 2, BLUE),
]
dots = load_maze()
# --- Main Game Loop ---
running = True
while running:
# 1. Event Handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
pacman.next_direction = "UP"
if event.key == pygame.K_DOWN:
pacman.next_direction = "DOWN"
if event.key == pygame.K_LEFT:
pacman.next_direction = "LEFT"
if event.key == pygame.K_RIGHT:
pacman.next_direction = "RIGHT"
if not game_over:
# 2. Update Game State
pacman.update()
for ghost in ghosts:
ghost.update()
# Check for dot collection
for dot in dots[:]:
distance = ((pacman.x - dot[0])**2 + (pacman.y - dot[1])**2)**0.5
if distance < CELL_SIZE // 2:
dots.remove(dot)
score += 10
# Check for ghost collision
for ghost in ghosts:
distance = ((pacman.x - ghost.x)**2 + (pacman.y - ghost.y)**2)**0.5
if distance < CELL_SIZE // 2:
game_over = True
# Check for win condition
if not dots:
game_over = True # You win!
# 3. Drawing
screen.fill(BLACK)
# Draw maze
for y, row in enumerate(MAZE):
for x, cell in enumerate(row):
if cell == 1:
pygame.draw.rect(screen, BLUE, (x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE))
# Draw dots
for dot in dots:
pygame.draw.circle(screen, WHITE, dot, 5)
# Draw game objects
pacman.draw(screen)
for ghost in ghosts:
ghost.draw(screen)
# Draw score
score_text = font.render(f"Score: {score}", True, WHITE)
screen.blit(score_text, (10, 10))
# Draw game over message
if game_over:
if not dots:
message = "YOU WIN!"
else:
message = "GAME OVER"
game_over_text = font.render(message, True, WHITE)
text_rect = game_over_text.get_rect(center=(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2))
screen.blit(game_over_text, text_rect)
# 4. Update Display
pygame.display.flip()
clock.tick(FPS)
# Quit Pygame
pygame.quit()
sys.exit()
How to Run It
Save the file and run it from your terminal:
python pacman_game.py
Next Steps and Improvements
This is a great starting point. Here are some ideas to make it even better:
- Pac-Man Animation: Instead of a static circle, draw Pac-Man with his mouth opening and closing. You can do this by drawing a
pacmanshape usingpygame.draw.arc()and changing the start and end angles. - Better Ghost AI: Instead of random movement, implement simple AI like:
- Chasing: The ghost tries to move towards Pac-Man's current position.
- Patrolling: The ghost has a set path it follows.
- Frightened Mode: When Pac-Man eats a power pellet, the ghosts become blue and try to run away from Pac-Man.
- Power Pellets: Add larger dots (e.g.,
3in your maze array) that, when eaten, allow Pac-Man to eat the ghosts for a short period. - Sound Effects: Add sounds for eating dots, eating ghosts, and the game over music using
pygame.mixer. - More Mazes: Create multiple maze layouts and allow the player to progress through them.
- Lives System: Give the player 3 lives instead of just one.
