Build the classic Snake Game with Python:A Complete Tutorial
Learn Python by building the classic Snake game! Our complete tutorial offers step-by-step instructions to code your own retro masterpiece. Start coding now!
@Harry

Building the classic Snake game is an excellent project for anyone looking to dive into game development with Python. It teaches fundamental concepts like game loops, event handling, collision detection, and basic graphics. This tutorial will guide you through creating your own Snake game using the Pygame library, a popular choice for 2D game development in Python.
Build the Classic Snake Game with Python: A Complete Tutorial
Introduction
Remember the satisfying crunch as your snake devoured an apple, growing longer and longer, the tension rising with every segment added? The classic Snake game, simple yet endlessly engaging, has captivated generations. It's more than just a nostalgic pastime; it's a perfect learning ground for aspiring game developers.
In this comprehensive tutorial, we'll build the classic Snake game from scratch using Python and the powerful Pygame library. You'll learn the core principles of game development, from setting up your game window to handling player input, managing game objects, detecting collisions, and creating a responsive game loop. By the end, you'll have a fully functional Snake game and a solid foundation for your next Python game project!
What You'll Learn:
- Setting up a Pygame window.
- Drawing shapes and objects on the screen.
- Handling keyboard input for player movement.
- Implementing a game loop.
- Managing game state (snake position, food position, score).
- Detecting collisions (snake with food, snake with walls, snake with itself).
- Displaying text (score, game over messages).
Prerequisites:
- Basic understanding of Python programming (variables, loops, functions, lists).
- Python 3 installed on your system.
- Pygame library installed: If you don't have it, open your terminal or command prompt and run:
pip install pygame
Step 1: Setting Up the Pygame Window
Every Pygame game starts with initializing the library and creating a display window. This window will be where all our game elements are drawn.
# snake_game.py
import pygame
import random
import sys
# --- 1. Initialize Pygame ---
pygame.init()
# --- 2. Define Colors (RGB) ---
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255) # For food, just an example
# --- 3. Screen Dimensions ---
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 400
CELL_SIZE = 20 # Size of each snake segment and food item
# --- 4. Set up the display ---
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Classic Python Snake Game")
# --- 5. Game Clock (for controlling frame rate) ---
clock = pygame.time.Clock()
FPS = 10 # Frames per second, controls game speed
print("Pygame initialized and window created!")
Explanation:
pygame.init(): Initializes all the Pygame modules required to get things running.WHITE,BLACK, etc.: We define common colors using their RGB (Red, Green, Blue) values.SCREEN_WIDTH,SCREEN_HEIGHT: These define the resolution of our game window.CELL_SIZEwill determine the size of our snake segments and food.pygame.display.set_mode(): Creates the actual window.pygame.display.set_caption(): Sets the title of the window.pygame.time.Clock(): Creates a Clock object which will help us control the game's frame rate.FPS: Defines how many times per second our game loop will run. A higher FPS means a faster snake.
Step 2: Defining Game Elements - Snake and Food
Now let's define the initial state of our game objects: the snake and the food.
# (Add this below the FPS definition in your snake_game.py file)
# --- 6. Snake Properties ---
snake_pos = [[100, 50], [90, 50], [80, 50]] # Initial snake body segments
snake_direction = 'RIGHT' # Initial movement direction
# --- 7. Food Properties ---
food_pos = [random.randrange(1, (SCREEN_WIDTH//CELL_SIZE)) * CELL_SIZE,
random.randrange(1, (SCREEN_HEIGHT//CELL_SIZE)) * CELL_SIZE]
food_spawn = True # Flag to check if new food needs to be spawned
# --- 8. Score ---
score = 0
# --- 9. Game Over State ---
game_over = False
# --- 10. Fonts for text display ---
font_style = pygame.font.SysFont("bahnschrift", 25)
score_font = pygame.font.SysFont("comicsansms", 35)
print("Snake, Food, and Score initialized!")
Explanation:
snake_pos: A list of lists, where each inner list[x, y]represents the coordinates of a snake segment. We start with a 3-segment snake.snake_direction: A string indicating the current direction of the snake.food_pos: A list[x, y]for the food's coordinates. We userandom.randrangeto place it randomly within the screen grid defined byCELL_SIZE.food_spawn: A boolean flag.score: Initializes the player's score to 0.game_over: A boolean flag to track the game's state.font_style,score_font: Pygame's font module allows us to render text. We pick a font and size here.
Step 3: Drawing Functions
Let's create helper functions to draw our snake, food, and display the score.
# (Add this below the font definitions)
# --- 11. Helper Functions for Drawing ---
def draw_snake(snake_body):
for segment in snake_body:
pygame.draw.rect(screen, GREEN, pygame.Rect(segment[0], segment[1], CELL_SIZE, CELL_SIZE))
def draw_food(food_pos_data):
pygame.draw.rect(screen, BLUE, pygame.Rect(food_pos_data[0], food_pos_data[1], CELL_SIZE, CELL_SIZE))
def display_score(score_val):
value = score_font.render("Your Score: " + str(score_val), True, WHITE)
screen.blit(value, [0, 0]) # Display at top-left corner
def message(msg, color):
mesg = font_style.render(msg, True, color)
screen.blit(mesg, [SCREEN_WIDTH / 6, SCREEN_HEIGHT / 3]) # Center the message
Explanation:
draw_snake(): Iterates through thesnake_bodylist and draws a green rectangle for each segment.pygame.Rect(x, y, width, height)creates a rectangle object.draw_food(): Draws a blue rectangle for the food at its current position.display_score(): Renders the current score using thescore_fontand displays it on the screen.render()creates a surface with the text, andblit()draws that surface onto our main screen.message(): A generic function to display messages (like "Game Over") on the screen.
Step 4: The Game Loop - Core Mechanics
The game loop is the heart of any game. It continuously:
- Handles user input (events).
- Updates the game state (move snake, check collisions).
- Draws everything on the screen.
- Controls the game's speed.
# (Add this below all functions)
# --- 12. Game Loop ---
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
# Handle keyboard input
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP and snake_direction != 'DOWN':
snake_direction = 'UP'
if event.key == pygame.K_DOWN and snake_direction != 'UP':
snake_direction = 'DOWN'
if event.key == pygame.K_LEFT and snake_direction != 'RIGHT':
snake_direction = 'LEFT'
if event.key == pygame.K_RIGHT and snake_direction != 'LEFT':
snake_direction = 'RIGHT'
# --- 13. Move the Snake ---
head_x, head_y = snake_pos[0]
if snake_direction == 'UP':
head_y -= CELL_SIZE
elif snake_direction == 'DOWN':
head_y += CELL_SIZE
elif snake_direction == 'LEFT':
head_x -= CELL_SIZE
elif snake_direction == 'RIGHT':
head_x += CELL_SIZE
new_head = [head_x, head_y]
snake_pos.insert(0, new_head) # Add new head
# --- 14. Check for Food Collision ---
if head_x == food_pos[0] and head_y == food_pos[1]:
score += 10
food_spawn = False
else:
snake_pos.pop() # Remove tail if no food eaten
# --- 15. Spawn New Food ---
if not food_spawn:
food_pos = [random.randrange(1, (SCREEN_WIDTH//CELL_SIZE)) * CELL_SIZE,
random.randrange(1, (SCREEN_HEIGHT//CELL_SIZE)) * CELL_SIZE]
# Ensure new food doesn't spawn on the snake
while food_pos in snake_pos:
food_pos = [random.randrange(1, (SCREEN_WIDTH//CELL_SIZE)) * CELL_SIZE,
random.randrange(1, (SCREEN_HEIGHT//CELL_SIZE)) * CELL_SIZE]
food_spawn = True
# --- 16. Check for Game Over Conditions ---
# Wall collision
if head_x < 0 or head_x >= SCREEN_WIDTH or head_y < 0 or head_y >= SCREEN_HEIGHT:
game_over = True
# Self-collision (snake head hits its own body)
for segment in snake_pos[1:]: # Check all segments except the head
if new_head == segment:
game_over = True
break # No need to check further segments
# --- 17. Drawing everything ---
screen.fill(BLACK) # Clear the screen each frame
draw_snake(snake_pos)
draw_food(food_pos)
display_score(score)
# --- 18. Update the display ---
pygame.display.update() # Or pygame.display.flip()
# --- 19. Control frame rate ---
clock.tick(FPS)
# --- 20. After Game Over Loop ---
while game_over:
screen.fill(BLACK)
message("You Lost! Press Q-Quit or C-Play Again", RED)
display_score(score) # Show final score
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
pygame.quit()
sys.exit()
if event.key == pygame.K_c:
# Reset game state to play again
game_over = False
snake_pos = [[100, 50], [90, 50], [80, 50]]
snake_direction = 'RIGHT'
food_pos = [random.randrange(1, (SCREEN_WIDTH//CELL_SIZE)) * CELL_SIZE,
random.randrange(1, (SCREEN_HEIGHT//CELL_SIZE)) * CELL_SIZE]
food_spawn = True
score = 0
# Important: reset FPS or speed if it increased with score
FPS = 10
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# --- 21. Quit Pygame ---
pygame.quit()
sys.exit()
Explanation of the Game Loop:
while not game_over:: This is our main game loop. It continues as long asgame_overisFalse.- Event Handling (
for event in pygame.event.get():):pygame.QUIT: Handles closing the window via the 'X' button.pygame.KEYDOWN: Detects when a key is pressed. We check for arrow keys (or WASD, if you prefer) and updatesnake_directionaccordingly. We also prevent the snake from immediately reversing direction (e.g., going 'UP' and then instantly 'DOWN').
- Move the Snake:
- We get the current head's coordinates (
head_x,head_y). - Based on
snake_direction, we calculate thenew_headcoordinates. snake_pos.insert(0, new_head): Adds thenew_headto the beginning of the list.
- We get the current head's coordinates (
Running Your Game
- Save the code: Save the entire code above into a file named
snake_game.py. - Open a terminal/command prompt: Navigate to the directory where you saved the file.
- Run the game: Execute the command:
python snake_game.py
You should now see your classic Snake game running!
Next Steps and Enhancements
Congratulations! You've built a fully functional classic Snake game. But the journey doesn't have to end here. Here are some ideas to enhance your game and further your learning:
- Increase Speed: Make
FPSgradually increase with the score to make the game more challenging. - Sounds: Add sound effects for eating food, game over, etc., using
pygame.mixer. - High Score: Save the highest score to a file and display it.
- Different Food Types: Introduce different types of food that might give more points or have special effects.
- Obstacles: Add static or moving obstacles to the game area.
- Pause Functionality: Implement a pause button.
- Start Screen/Menu: Create a proper start menu before the game begins.
- Levels: Introduce different levels with varying difficulties or layouts.
- Wrap Around: Instead of dying when hitting walls, make the snake appear on the opposite side of the screen.
Conclusion
Building the Snake game is a rite of passage for many aspiring game developers, and for good reason. It provides a practical, hands-on understanding of core game development concepts in a manageable project. You've learned how to harness the power of Python and Pygame to bring a nostalgic classic to life.
This tutorial gives you a solid foundation. Now, go forth, experiment, and customize your game! The world of Python game development is vast and exciting, and you've just taken a significant step into it. Happy coding!