Sitemap

Pygame Snake

13 min readJun 30, 2024

--

If you think you need to spend $2,000 on a 120-day program to become a data scientist, then listen to me for a minute.

Press enter or click to view image in full size

I understand that learning data science can be really challenging, especially when you are just starting out, because you don’t know what you should know.

But it doesn’t have to be this way.

That’s why I spent nearly 97 hours curating a list of 101+ resources that will help you become a data scientist in 90 days.

You can check it out here.

Now let’s get back to the blog:

The Snake game is a classic and timeless arcade game that has been captivating players since its inception. In this game, you control a snake that moves around the screen, eating food to grow longer while avoiding collisions with the walls or itself. The objective is simple yet addictive: keep growing the snake as long as possible without crashing.

The simplicity of the Snake game makes it a perfect project for beginners in game development. Not only does it help you grasp essential programming concepts, but it also introduces you to the fundamentals of game design and logic. From handling user input to implementing collision detection, the Snake game covers a wide array of skills you’ll need as you delve deeper into game development.

By the end of this tutorial, you will have built your own version of this classic game using Pygame, a popular Python library for creating games. This will not only boost your confidence but also give you a solid foundation to tackle more complex projects in the future.

What is Our Objective?
The goal of this tutorial is to guide you step-by-step in creating a fully functional Snake game using Pygame. I will walk you through the entire process, from setting up your development environment to implementing the game mechanics and enhancing the gameplay with additional features. Here’s a brief overview of what we will cover:

  • Setting Up: You’ll learn how to install Python and Pygame, and set up your development environment.
  • Game Window: We’ll create the game window and understand how to manage the display.
  • Game Logic: You’ll implement the core game mechanics, including snake movement, food generation, and collision detection.
  • Enhancements: We’ll add features like sound effects, a scoring system, and difficulty levels to make the game more engaging.
  • Troubleshooting: Finally, I’ll help you debug common issues and answer frequently asked questions.

Throughout this tutorial, I will provide detailed explanations and code snippets to ensure you understand each step. By following along, you’ll not only complete the Snake game but also gain valuable insights into game development with Pygame.

Prerequisites
Before we dive into the tutorial, let’s make sure you have the basic knowledge and tools required to follow along smoothly. Here’s what you need:

  • Basic Python Knowledge: You should be comfortable with Python basics such as variables, loops, functions, and conditionals. If you’re new to Python, consider completing a beginner’s tutorial first.
  • Pygame Installed: We’ll be using Pygame, a library that simplifies game development in Python. If you haven’t installed it yet, don’t worry — I’ll show you how to do it.
  • Text Editor or IDE: You’ll need a text editor or an Integrated Development Environment (IDE) to write your code. Popular choices include VS Code, PyCharm, and Sublime Text.

Here’s a quick guide to get you started with installing Python and Pygame:

Installing Python:

  1. Visit the official Python website.
  2. Download and install the latest version of Python for your operating system.
  3. Ensure Python is added to your system PATH during installation.

Installing Pygame:

  1. Open your command prompt or terminal.
  2. Run the following command to install Pygame via pip:
pip install pygame

4. Verify the installation by running a simple Pygame script or checking the installed packages.

By ensuring you have these prerequisites, you’ll be well-prepared to follow along with the tutorial and build your own Snake game. Let’s get started on this exciting journey into game development with Pygame!

let’s dive deep into creating the game window and setting up the initial game variables and constants. I’ll guide you through each step with detailed explanations to ensure you grasp the concepts thoroughly.

Step #1: Creating the Game Window

Initializing Pygame

To start developing your game with Pygame, the first thing you need to do is initialize the Pygame library. This step sets up the necessary configurations and prepares Pygame to manage game assets and events. Here’s how you do it:

import pygame

# Initialize Pygame
pygame.init()
  • Importing Pygame: First, you need to import the Pygame library. This allows you to access all the functions and classes that Pygame provides.
  • pygame.init(): This function initializes all the Pygame modules that are required for your game. It’s a good practice to call this function at the beginning of your script to ensure everything is set up properly.

By initializing Pygame, you’re making sure that all the modules you’ll be using are ready to go. This step is crucial for setting up the game environment.

Setting the Window Size
Next, you need to create the game window where your Snake game will be displayed. The size of this window is defined by its width and height. Here’s how you can set it up:

# Set up the game window dimensions
screen_width = 640
screen_height = 480

# Create the game window
screen = pygame.display.set_mode((screen_width, screen_height))
  • screen_width and screen_height: These variables define the dimensions of your game window. You can adjust these values based on how large or small you want your game window to be.
  • pygame.display.set_mode(): This function creates the game window with the specified width and height. The screen variable holds the reference to this window, which you’ll use later to draw game elements.

By defining the window size, you’re setting the stage for your game. This step ensures that your game has a defined area where all the action will take place.

Setting the Title
To make your game more polished and identifiable, you should set a title for the game window. This title will appear at the top of the window and give your game a professional touch. Here’s how to do it:

# Set the window title
pygame.display.set_caption('Snake Game')
  • pygame.display.set_caption(): This function sets the title of the game window. The title you choose will be displayed at the top of the window, making it clear what game is being played.

By setting a title, you add a small but important detail that enhances the user experience.

Step #2: Game Variables and Constants

Defining Colors

Colors are an essential part of any game. In Pygame, colors are defined using RGB tuples, where each component (Red, Green, Blue) can have a value between 0 and 255. Here’s how you can define some basic colors:

# Define colors using RGB tuples
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
  • RGB Tuples: Each color is represented as a tuple of three integers. For example, (255, 0, 0) represents the color red because the red component is at its maximum value while the green and blue components are zero.

By defining colors, you create a palette that you can use throughout your game to draw various elements like the snake, the food, and the background.

Setting Up Game Variables
To manage the game’s behavior and state, you need to set up various variables. These variables will control aspects like the speed of the snake, the dimensions of the game area, and more. Here are some of the key variables you’ll need:

# Game variables
snake_speed = 15 # Speed of the snake
screen_width = 640
screen_height = 480
cell_size = 20 # Size of each grid cell
  • snake_speed: This variable controls how fast the snake moves. You can adjust it to make the game easier or more challenging.
  • screen_width and screen_height: These variables define the dimensions of the game window, as mentioned earlier.
  • cell_size: This variable defines the size of each cell in the grid. It helps in positioning the snake and food precisely on the game screen.

By setting up these variables, you lay the groundwork for the game mechanics and visual presentation.

Get Amit Yadav’s stories in your inbox

Join Medium for free to get updates from this writer.

Creating the Snake
In the Snake game, the snake itself is represented as a list of coordinates. Each coordinate corresponds to a segment of the snake’s body. Here’s how you can initialize the snake:

# Snake variables
snake_pos = [100, 50] # Initial position of the snake's head
snake_body = [[100, 50], [90, 50], [80, 50]] # Initial body segments of the snake
direction = 'RIGHT' # Initial direction of the snake's movement
change_to = direction # Direction to change to based on user input
  • snake_pos: This variable holds the coordinates of the snake’s head. Initially, the snake’s head is positioned at (100, 50).
  • snake_body: This list contains the coordinates of the snake’s body segments. The snake starts with three segments positioned horizontally.
  • direction: This variable indicates the current direction of the snake’s movement. Initially, it’s set to ‘RIGHT’.
  • change_to: This variable is used to store the new direction based on user input before updating the actual direction.

By representing the snake as a list of coordinates, you can easily manage its movement, growth, and collision detection.

Putting It All Together
Here’s the complete code snippet for initializing Pygame, setting up the game window, and defining the initial game variables and constants:

import pygame

# Initialize Pygame
pygame.init()

# Set up the game window dimensions
screen_width = 640
screen_height = 480
screen = pygame.display.set_mode((screen_width, screen_height))

# Set the window title
pygame.display.set_caption('Snake Game')

# Define colors using RGB tuples
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)

# Game variables
snake_speed = 15
cell_size = 20

# Snake variables
snake_pos = [100, 50]
snake_body = [[100, 50], [90, 50], [80, 50]]
direction = 'RIGHT'
change_to = direction

By following these steps, you’ve set up the foundation for your Snake game. You’re now ready to implement the game logic and bring your Snake game to life. Keep this momentum going as we dive deeper into the game development process!

Step #3: Main Game Loop

The main game loop is the heart of your game, where all the game logic is executed continuously until the game ends. Let’s break down each component of the main game loop.

Handling Events
Handling events is crucial for responding to user input, such as keyboard presses or quitting the game. Here’s how you can handle these events:

# Main game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
change_to = 'UP'
elif event.key == pygame.K_DOWN:
change_to = 'DOWN'
elif event.key == pygame.K_LEFT:
change_to = 'LEFT'
elif event.key == pygame.K_RIGHT:
change_to = 'RIGHT'

# Validate direction
if change_to == 'UP' and direction != 'DOWN':
direction = 'UP'
if change_to == 'DOWN' and direction != 'UP':
direction = 'DOWN'
if change_to == 'LEFT' and direction != 'RIGHT':
direction = 'LEFT'
if change_to == 'RIGHT' and direction != 'LEFT':
direction = 'RIGHT'
  • pygame.event.get(): This function retrieves all the events in the event queue.
  • pygame.QUIT: This event is triggered when the user attempts to close the window.
  • pygame.KEYDOWN: This event is triggered when a key is pressed. You can check which key was pressed using event.key.

By handling these events, you can manage user inputs effectively and control the game’s flow.

Step #4: Movement Logic

Updating the snake’s position based on user input is essential for the game’s dynamics. Here’s how you can do it:

# Update the position of the snake
if direction == 'UP':
snake_pos[1] -= cell_size
if direction == 'DOWN':
snake_pos[1] += cell_size
if direction == 'LEFT':
snake_pos[0] -= cell_size
if direction == 'RIGHT':
snake_pos[0] += cell_size

# Snake body growing mechanism
snake_body.insert(0, list(snake_pos))
  • Updating Position: Depending on the current direction, you update the snake’s head position by changing its coordinates.
  • Growing the Snake: Insert the new position of the snake’s head at the beginning of the snake body list.

This logic ensures that the snake moves smoothly based on the direction specified by the user.

Step #5: Collision Detection

Collision detection is critical for determining game over conditions. Here’s how you can detect collisions with the walls and the snake itself:

# Detect collision with wall
if snake_pos[0] < 0 or snake_pos[0] >= screen_width or snake_pos[1] < 0 or snake_pos[1] >= screen_height:
running = False

# Detect collision with itself
for block in snake_body[1:]:
if snake_pos == block:
running = False
  • Wall Collision: Check if the snake’s head position is outside the bounds of the game window.
  • Self Collision: Check if the snake’s head position matches any of its body segments.

These checks help in determining when the game should end due to a collision.

Step #6: Adding the Food

Adding food to the game involves placing it randomly on the screen and checking if the snake eats it. Here’s how to do it:

import random

# Initial food position
food_pos = [random.randrange(1, (screen_width // cell_size)) * cell_size,
random.randrange(1, (screen_height // cell_size)) * cell_size]
food_spawn = True

# Check if the snake eats the food
if snake_pos == food_pos:
food_spawn = False
else:
snake_body.pop()

if not food_spawn:
food_pos = [random.randrange(1, (screen_width // cell_size)) * cell_size,
random.randrange(1, (screen_height // cell_size)) * cell_size]
food_spawn = True
  • Random Position: Use random.randrange() to generate a random position for the food within the game window.
  • Eating Food: If the snake’s head position matches the food position, spawn new food.

This logic ensures that food appears randomly and the snake can grow by eating it.

Growing the Snake

When the snake eats the food, it grows longer. This is handled by the insert method used earlier and by not removing the last segment of the snake’s body:

# Snake body growing mechanism
snake_body.insert(0, list(snake_pos))

# If the snake eats the food, do not remove the last segment
if snake_pos != food_pos:
snake_body.pop()

This ensures that the snake grows correctly when it eats food.

Step #7: Drawing the Game Elements

Drawing the game elements involves rendering the snake and the food on the screen.

Drawing the Snake
To draw the snake on the screen, you loop through the snake body and draw each segment:

# Draw the snake
for pos in snake_body:
pygame.draw.rect(screen, green, pygame.Rect(pos[0], pos[1], cell_size, cell_size))
  • pygame.draw.rect(): This function draws a rectangle on the screen. The color, position, and size of the rectangle are specified as parameters.

Drawing the Food
Similarly, you draw the food using the same method:

# Draw the food
pygame.draw.rect(screen, red, pygame.Rect(food_pos[0], food_pos[1], cell_size, cell_size))

This draws the food at the specified position.

Step #8: Updating the Screen

After drawing all game elements, you need to update the display to reflect the current game state:

# Fill the background
screen.fill(black)

# Draw the snake and food
for pos in snake_body:
pygame.draw.rect(screen, green, pygame.Rect(pos[0], pos[1], cell_size, cell_size))

pygame.draw.rect(screen, red, pygame.Rect(food_pos[0], food_pos[1], cell_size, cell_size))

# Update the display
pygame.display.update()
  • screen.fill(): This fills the screen with the background color.
  • pygame.display.update(): This function updates the display to show the latest changes.

Step #9: Game Over Conditions

Defining Game Over
Game over conditions are defined by collisions. If the snake collides with the wall or itself, the game should end. This is already covered in the collision detection logic.

Displaying Game Over Message
To display a game over message, you need to render text on the screen. Here’s how you can do it:

# Define the font and size
font = pygame.font.SysFont('times new roman', 50)
game_over_surface = font.render('Your Score : ' + str(len(snake_body) - 3), True, red)
game_over_rect = game_over_surface.get_rect()
game_over_rect.midtop = (screen_width / 2, screen_height / 4)

# Display the game over message
screen.fill(black)
screen.blit(game_over_surface, game_over_rect)
pygame.display.flip()

# Wait for a few seconds before closing the game
pygame.time.sleep(2)
  • pygame.font.SysFont(): This function creates a font object.
  • font.render(): This renders the text as a surface.
  • screen.blit(): This draws the text surface on the screen.
  • pygame.time.sleep(): This pauses the game for a few seconds before closing.

By following these steps, you ensure that the game provides feedback to the player when it ends, enhancing the overall user experience.

Step #10: Complete Code for the Main Game Loop

Here’s the complete code for the main game loop, including event handling, movement logic, collision detection, drawing game elements, and handling game over conditions:

import pygame
import random
import time

# Initialize Pygame
pygame.init()

# Set up the game window dimensions
screen_width = 640
screen_height = 480
screen = pygame.display.set_mode((screen_width, screen_height))

# Set the window title
pygame.display.set_caption('Snake Game')

# Define colors using RGB tuples
white = (255, 255, 255)
black = (0, 0, 0)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)

# Game variables
snake_speed = 15
cell_size = 20

# Snake variables
snake_pos = [100, 50]
snake_body = [[100, 50], [90, 50], [80, 50]]
direction = 'RIGHT'
change_to = direction

# Initial food position
food_pos = [random.randrange(1, (screen_width // cell_size)) * cell_size,
random.randrange(1, (screen_height // cell_size)) * cell_size]
food_spawn = True

# Main game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
change_to = 'UP'
elif event.key == pygame.K_DOWN:
change_to = 'DOWN'
elif event.key == pygame.K_LEFT:
change_to = 'LEFT'
elif event.key == pygame.K_RIGHT:
change_to = 'RIGHT'

# Validate direction
if change_to == 'UP' and direction != 'DOWN':
direction = 'UP'
if change_to == 'DOWN' and direction != 'UP':
direction = 'DOWN'
if change_to == 'LEFT' and direction != 'RIGHT':
direction = 'LEFT'
if change_to == 'RIGHT' and direction != 'LEFT':
direction = 'RIGHT'

# Update the position of the snake
if direction == 'UP':
snake_pos[1] -= cell_size
if direction == 'DOWN':
snake_pos[1] += cell_size
if direction == 'LEFT':
snake_pos[0] -= cell_size
if direction == 'RIGHT':
snake_pos[0] += cell_size

# Snake body growing mechanism
snake_body.insert(0, list(snake_pos))

# Check if the snake eats the food
if snake_pos == food_pos:
food_spawn = False
else:
snake_body.pop()

if not food_spawn:
food_pos = [random.randrange(1, (screen_width // cell_size)) * cell_size,
random.randrange(1, (screen_height // cell_size)) * cell_size]
food_spawn = True

# Detect collision with wall
if snake_pos[0] < 0 or snake_pos[0] >= screen_width or snake_pos[1] < 0 or snake_pos[1] >= screen_height:
running = False

# Detect collision with itself
for block in snake_body[1:]:
if snake_pos == block:
running = False

# Fill the background
screen.fill(black)

# Draw the snake and food
for pos in snake_body:
pygame.draw.rect(screen, green, pygame.Rect(pos[0], pos[1], cell_size, cell_size))

pygame.draw.rect(screen, red, pygame.Rect(food_pos[0], food_pos[1], cell_size, cell_size))

# Update the display
pygame.display.update()

# Set the speed of the snake
pygame.time.Clock().tick(snake_speed)

# Display game over message
font = pygame.font.SysFont('times new roman', 50)
game_over_surface = font.render('Your Score : ' + str(len(snake_body) - 3), True, red)
game_over_rect = game_over_surface.get_rect()
game_over_rect.midtop = (screen_width / 2, screen_height / 4)
screen.fill(black)
screen.blit(game_over_surface, game_over_rect)
pygame.display.flip()
time.sleep(2)

# Quit the game
pygame.quit()

Ending Note

By following this guide, you’ll have a fully functional Snake game in Pygame that covers all the essential aspects, from initialization to game over conditions. This detailed explanation should help you understand each part of the game development process, allowing you to create and customize your own games in the future.

--

--

Amit Yadav
Amit Yadav

Written by Amit Yadav

Get Data Science Roadmap for Your First Data Science Job : https://amit404.gumroad.com/l/ds-diary