Step-by-Step Guide to Build Python Snake Game with Pygame
Published: 2023-06-09 15:48:26

Snake games have been a beloved classic in the world of computer games for decades. You might have seen your parents or even grandparents enjoy these simple yet addictive games on their ancient cell phones or computers. But did you know that you can create your own version of a snake game using the Python programming language?

In this article, we will explore how to make a basic Python snake game using the Pygame library. Pygame is a powerful tool that allows us to create engaging and interactive games using Python. By the end of this tutorial, you will have a solid understanding of the game development process and be able to create your very own snake game.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/env8ay83t00ceipg2sa5.png)

Snake games gained popularity in the late 1970s and early 1980s when they were introduced on arcade machines. They quickly became a sensation due to their simplicity and addictive nature. The objective is straightforward: control a snake and guide it to eat food while avoiding collision with its own body or the game's boundaries. With each successful consumption, the snake grows longer, making it more challenging to maneuver.

Now, with the Pygame library, you can recreate this classic game with your own unique twist. Pygame provides a collection of functions and tools specifically designed for game development, making it an excellent choice for aspiring game developers.

We will start from scratch, guiding you through each step of the process, from setting up the development environment to adding exciting features like sound effects and scoring systems. By the end, you'll have a fully functional snake game that you can proudly share with your friends and family.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z5elhpse7g5z4a98zeka.png)


## Setting up the Pygame Development Environment
Before we dive into creating our Python snake game, we need to make sure we have the necessary tools installed. First and foremost, we need to install Python, which is the programming language we will be using. You can download the latest version of Python from the official Python website (python.org) and follow the installation instructions specific to your operating system.

Once Python is installed, we can move on to installing Pygame. Pygame is a third-party library that provides functionality for creating games in Python. To install Pygame, open your command prompt or terminal and enter the following command:

```
pip install pygame
```

This command will download and install the Pygame library onto your system. After the installation is complete, we're ready to move on to the next step.

Alternatively, you can also skip all the download and installation process by using Lightly IDE. After logging into your workspace, simply create a Python project and select "Python Pygame Project" in the Template dropdown.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g48hp6ahxdse9ulz6h15.png)


To keep our game organized, it's a good practice to create a new Python project. This will ensure that all the necessary files and resources are stored in one place. Here's a step-by-step guide to setting up a new Python project:

1. Create a new folder on your computer with a suitable name for your project, such as "SnakeGame".
2. Open your favorite text editor or Integrated Development Environment (IDE) and create a new file inside the project folder.
3. Save the file with a Python script file extension, such as ".py". For example, you can save it as "snake_game.py".

## Importing the Pygame libraries and modules in Python
Now that we have our project set up, let's start by importing the required libraries and modules into our Python script. In this case, we will be using the Pygame library for game development. Open your "snake_game.py" file in your text editor or IDE and add the following lines of code at the beginning:

```py
import pygame
import sys
```

The pygame library provides the necessary functions and classes for game development, while the sys module allows us to interact with the system and handle events.

With the libraries and modules imported, we are ready to proceed with creating our snake game. In the next section, we will start by creating the game window and handling user input.

## Creating the Game Window in Python
Now that we have our development environment ready, it's time to create the game window. We'll be using Pygame to handle the window and graphics. Add the following lines of code after the import statements in your "snake_game.py" file:

```py
pygame.init()

# Set up the game window
window_width = 800
window_height = 600
game_window = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption("Python Snake Game")
```

The pygame.init() function initializes all the Pygame modules that we'll be using. It's important to call this function before any other Pygame function. Next, we define the dimensions of the game window using window_width and window_height variables. Adjust these values to fit your desired window size. The pygame.display.set_mode() function creates the actual game window, while pygame.display.set_caption() sets the title of the window.

Now that we have the game window set up, we need to handle user input and respond to events. We'll use a main game loop to continuously update the game state and handle events. Add the following code below the window setup:

```py
# Game loop
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # Update game state

    # Render graphics

    pygame.display.update()

# Quit the game and clean up resources
pygame.quit()
sys.exit()
```

In this code snippet, we start with a running variable set to True, which controls the main game loop. Inside the loop, we use pygame.event.get() to retrieve a list of all the events that have occurred since the last iteration. We iterate through these events using a for loop and check if the event type is pygame.QUIT. This event occurs when the user closes the game window, and in that case, we set running to False to exit the loop.

Between the event handling and rendering sections, you'll find two commented lines: # Update game state and # Render graphics. These are placeholders where we'll add the code to update the game state and draw the graphics in subsequent sections.

Lastly, we call pygame.display.update() to update the game window and display any changes made. This function is called within the main loop to ensure the window is refreshed each frame.

At the end of the code, we have the necessary lines to quit the game and clean up resources when the loop is exited.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8oaa0l0bg9oomis9ai17.png)


There is no snake or food yet. But with the game window set up and the event handling in place, we're ready to move on to creating the snake. In the next section, we'll design the snake's appearance and define its movement.

## Creating the Snake in Python using Pygame Library
Now that we have the game window set up, let's move on to creating the snake. We'll start by designing its appearance and determining its initial position. Add the following code after the pygame.display.update() line in your "snake_game.py" file:

```py
# Snake properties
snake_color = (0, 255, 0)  # Green color
snake_size = 20
snake_x = window_width // 2
snake_y = window_height // 2
snake_speed = 5

# Draw the snake
snake = pygame.Rect(snake_x, snake_y, snake_size, snake_size)
```

In the code above, we define the properties of the snake. The snake_color variable holds the RGB values (0, 255, 0) for green color. Feel free to change the color to your preference by modifying these values. The snake_size variable represents the width and height of the snake's body segments, and you can adjust it as desired.

We set the initial position of the snake's head using snake_x and snake_y. Here, we place it at the center of the game window by dividing the window dimensions by 2.

Finally, we create a snake rectangle using pygame.Rect(), which represents the snake's body. This rectangle allows us to easily manipulate and draw the snake on the game window.

## Defining the snake's movement and control:
Now that we have the snake's initial position, let's define its movement and control. Add the following code after the snake = pygame.Rect(snake_x, snake_y, snake_size, snake_size) line:

```py
# Snake movement
snake_dx = 0
snake_dy = 0

# Snake control
snake_speed_multiplier = 1

# Update snake position
snake.x += snake_dx * snake_speed * snake_speed_multiplier
snake.y += snake_dy * snake_speed * snake_speed_multiplier
```

In the code snippet above, we introduce two variables, snake_dx and snake_dy, which represent the snake's movement direction along the x-axis and y-axis respectively. We initialize both variables to 0, indicating that the snake starts at rest.

Next, we introduce a snake_speed_multiplier variable to control the speed of the snake. You can modify this value to adjust the speed to your liking.

Finally, we update the snake's position by adding the respective changes (snake_dx * snake_speed * snake_speed_multiplier and snake_dy * snake_speed * snake_speed_multiplier) to its x and y coordinates. This allows us to move the snake smoothly across the game window.

## Handling collisions with the boundaries of the game window:
To ensure that the snake stays within the game window, we need to handle collisions with the boundaries. Add the following code after the snake movement section:

```py
# Check if the snake hits the window boundaries
if snake.x < 0 or snake.x + snake_size > window_width or snake.y < 0 or snake.y + snake_size > window_height:
    # Handle game over logic here
    running = False
```

In this code, we check if the snake's x-coordinate is less than 0 or greater than the width of the game window, or if the snake's y-coordinate is less than 0 or greater than the height of the window. If any of these conditions are true, it means the snake has hit the boundaries of the window.

In the event of a collision, we can handle the game over logic by setting running to False, which will exit the main game loop and end the game.

## Implementing the Food for the Snake
To make the game more interesting, we need to add food for the snake to eat. Let's design the appearance of the food and randomly place it within the game window. Add the following code after the snake's section in your "snake_game.py" file:

```py
import random

# Food properties
food_color = (255, 0, 0)  # Red color
food_size = 20

# Place the food at a random position
food_x = random.randint(0, window_width - food_size)
food_y = random.randint(0, window_height - food_size)

# Draw the food
food = pygame.Rect(food_x, food_y, food_size, food_size)
```

In the code above, we introduce properties for the food, such as food_color (red color) and food_size. Modify these values to suit your preferences.

Next, we generate random x and y coordinates for the food using random.randint(). The range of random values ensures that the food is placed within the game window bounds.

Finally, we create a food rectangle using pygame.Rect() and pass the generated coordinates and the food size.

## Detecting collisions between the snake and the food
Now that we have the food placed within the game window, we need to detect when the snake collides with it. Add the following code inside the main game loop, before the rendering section:

```py
# Detect collisions between the snake and the food
if snake.colliderect(food):
    # Update the snake's length and score
    snake_size += 1
    score += 1

    # Place the food at a new random position
    food.x = random.randint(0, window_width - food_size)
    food.y = random.randint(0, window_height - food_size)
```

The code above checks if the snake collides with the food using the colliderect() method. If a collision occurs, it means the snake has eaten the food.

Upon detecting a collision, we update the snake's length by incrementing snake_size and increase the score by 1.

To provide continuous challenges, we also place the food at a new random position by generating new coordinates for the food rectangle.

## Updating the snake's length and score upon eating the food:
Now that we've detected the collision between the snake and the food, we need to update the snake's length and score. Add the following code before the rendering section:

```py
# Update the snake's length
snake_body.append(pygame.Rect(snake.x, snake.y, snake_size, snake_size))
if len(snake_body) > snake_size:
    del snake_body[0]
```

In this code, we introduce a list called snake_body to keep track of the snake's body segments. When the snake eats the food, we append a new rectangle representing the snake's body segment to the snake_body list.

If the length of snake_body exceeds snake_size (the desired length of the snake), we remove the oldest segment from the list using del to ensure that the snake maintains its length.

Remember to initialize the snake_body list before the main game loop:

```py
snake_body = []
```

Congratulations! You have successfully implemented the food in the snake game. The snake can now detect collisions with the food, update its length, and increase the score upon eating the food.

## Game Over and Restart for the Snake Game with Pygame
To ensure that the game ends when the snake collides with its own body, we need to check for collisions between the snake's head and its body segments. Add the following code inside the main game loop, before the rendering section:

```py
# Check for collisions between the snake's head and its body
if len(snake_body) > 1 and snake.colliderect(snake_body[i] for i in range(1, len(snake_body))):
    running = False
```

In this code, we check if the length of snake_body is greater than 1 (to ensure there is at least one body segment) and if the snake's head collides with any of its body segments. If a collision occurs, it means the snake has collided with itself, and we set running to False to end the game.

When the game ends, we want to display a game over message along with the final score. Add the following code after the main game loop:

```py
# Display the game over message and final score
game_over_font = pygame.font.Font(None, 48)  # Customize the font and size
game_over_text = game_over_font.render("Game Over", True, (255, 255, 255))  # White color

score_font = pygame.font.Font(None, 36)  # Customize the font and size
score_text = score_font.render("Final Score: " + str(score), True, (255, 255, 255))  # White color

game_window.blit(game_over_text, (window_width // 2 - game_over_text.get_width() // 2, window_height // 2 - 48))
game_window.blit(score_text, (window_width // 2 - score_text.get_width() // 2, window_height // 2))
pygame.display.update()
```

In this code, we define two font objects, game_over_font and score_font, to customize the font and size of the text. You can modify these fonts to your preference.

We then use render() to create text surfaces for the game over message and the final score. The message is displayed as "Game Over" in white color, and the score is displayed as "Final Score: " followed by the value of the score variable.

The blit() function is used to blit (draw) the text surfaces onto the game window. We position the game over message and score text at the center of the window.

## Implementing a restart option for the Snake Game with Pygame
To allow the player to restart the game after it ends, we can add a restart option. Add the following code after displaying the game over message and final score:

```py
restart_font = pygame.font.Font(None, 24)  # Customize the font and size
restart_text = restart_font.render("Press R to Restart", True, (255, 255, 255))  # White color

game_window.blit(restart_text, (window_width // 2 - restart_text.get_width() // 2, window_height // 2 + 48))
pygame.display.update()

while True:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN and event.key == pygame.K_r:
            # Restart the game
            running = True
            snake_body.clear()
            snake.x = window_width // 2
            snake.y = window_height // 2
            score = 0
    break
```

In this code, we display the restart message, "Press R to Restart", below the game over message and final score. After displaying the restart message, we enter a new while loop to continuously check for the "R" key to be pressed. If the player presses the "R" key, we reset the game by setting running to True, clearing the snake_body list, resetting the snake's position, and resetting the score to 0.

## Controlling the speed and difficulty of the Python Snake game
To make the game more engaging, we can add control over the speed and difficulty. We can introduce a speed multiplier that increases as the snake eats more food. Add the following code inside the main game loop, after updating the snake's position:

```py
# Increase the snake's speed based on the score
if score > 0 and score % 5 == 0:
    snake_speed_multiplier += 0.1
```

In this code, we check if the score is greater than 0 and if it is divisible evenly by 5. If both conditions are met, we increment the snake_speed_multiplier by 0.1. This increases the speed of the snake, making the game gradually more challenging as the score increases.

Feel free to adjust the increment value to your preference to control the rate of speed increase.

## Implementing a scoring system in the Python Snake Game Code
To provide a sense of progression, we can implement a scoring system that keeps track of the player's score. Add the following code inside the main game loop, before rendering the graphics:

```py
# Display the score
score_font = pygame.font.Font(None, 24)  # Customize the font and size
score_text = score_font.render("Score: " + str(score), True, (255, 255, 255))  # White color
game_window.blit(score_text, (10, 10))
```

In this python snake game code, we define a font object score_font to customize the font and size of the score text. We then use render() to create a text surface with the score value. The score is displayed as "Score: " followed by the value of the score variable.

Adjust the position (10, 10) to change the location of the score display on the game window.

To make the game more competitive, we can track and display the high score achieved by the player. Add the following code after initializing the game logic variables:

```py
# Tracking and displaying the high score
high_score = 0

# Load the high score from a file (e.g., "high_score.txt")
try:
    with open("high_score.txt", "r") as file:
        high_score = int(file.read())
except FileNotFoundError:
    pass

# Display the high score
high_score_text = score_font.render("High Score: " + str(high_score), True, (255, 255, 255))  # White color
game_window.blit(high_score_text, (10, 40))
```

In this code, we introduce a high_score variable to store the highest score achieved by the player. We attempt to load the high score from a file (e.g., "high_score.txt"), and if the file is not found or cannot be read, we continue with the default value of 0 for the high score.

Next, we create a text surface high_score_text to display the high score. The high score is shown as "High Score: " followed by the value of the high_score variable.

Again, you can adjust the position (10, 40) to change the location of the high score display on the game window.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bcoo2cbhmpczonycl1rf.png)


## Adding sound effects and music to the Python Snake Game Code
To make the game more immersive, we can add sound effects for various events such as eating food, collision, and game over. Additionally, background music can be played during gameplay. Here's how you can incorporate sound effects and music into the game:

Load sound files:
```py
# Load sound effects
eat_sound = pygame.mixer.Sound("eat_sound.wav")
collision_sound = pygame.mixer.Sound("collision_sound.wav")
game_over_sound = pygame.mixer.Sound("game_over_sound.wav")

# Load background music
pygame.mixer.music.load("background_music.mp3")
```

Make sure to replace the filenames with the actual sound and music files you want to use. Place these lines of code after initializing Pygame.

Play sound effects and music at appropriate events:
```py
# Handling collisions between the snake and the food
if snake.colliderect(food):
    # Update the snake's length and score
    snake_size += 1
    score += 1

    # Play eat sound effect
    eat_sound.play()

    # Place the food at a new random position
    food.x = random.randint(0, window_width - food_size)
    food.y = random.randint(0, window_height - food_size)

# Handling collisions with the boundaries of the game window
if (
    snake.x < 0
    or snake.x + snake_size > window_width
    or snake.y < 0
    or snake.y + snake_size > window_height
):
    running = False
    # Play collision sound effect
    collision_sound.play()

# Displaying the game over message and final score
if not running:
    # Play game over sound effect
    game_over_sound.play()

# Play background music
pygame.mixer.music.play(-1)  # -1 plays the music in an infinite loop
```

Add the sound effect and music playback code at appropriate places in the game loop. Ensure that the sound and music files exist in the specified paths.

## Customizing the game window and graphics
To make the game visually appealing, you can customize the game window and graphics. Here are a few ideas:

Set a background image:
# Load and resize the background image
background_image = pygame.image.load("background_image.png")
background_image = pygame.transform.scale(background_image, (window_width, window_height))

# Rendering graphics
game_window.blit(background_image, (0, 0))  # Draw the background image
Replace "background_image.png" with the path to your desired background image. Place these lines of code before rendering other graphics in the game window.

Customize snake and food appearance:
# Customizing snake appearance
snake_color = (0, 255, 0)  # Green color
snake_head_image = pygame.image.load("snake_head.png")
snake_head_image = pygame.transform.scale(snake_head_image, (snake_size, snake_size))

# Customizing food appearance
food_color = (255, 0, 0)  # Red color
food_image = pygame.image.load("food.png")
food_image = pygame.transform.scale(food_image, (food_size, food_size))

# Rendering graphics
pygame.draw.rect(game_window, snake_color, snake_head_image.get_rect(topleft=(snake.x, snake.y)))  # Draw the snake head
pygame.draw.rect(game_window, food_color, food_image.get_rect(topleft=(food.x, food.y)))  # Draw the food
Replace "snake_head.png" and "food.png" with the paths to your desired snake head and food images. Adjust the colors or image sizes according to your preference. Place these lines of code instead of the previous pygame.draw.rect() calls.

## Implementing a game menu and options for the Python Snake Game Code
To provide a better user experience, you can implement a game menu with options such as starting a new game, adjusting difficulty, or accessing high scores. Here's a basic outline for implementing a game menu:

Create a function to handle the game menu:
```py
def game_menu():
    # Display the menu options
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    return  # Exit the menu and start the game

        # Rendering graphics
        game_window.fill((0, 0, 0))  # Fill the game window with black color

        # Draw the menu options
        menu_font = pygame.font.Font(None, 36)  # Customize the font and size
        start_text = menu_font.render("Press Enter to Start", True, (255, 255, 255))  # White color

        game_window.blit(start_text, (window_width // 2 - start_text.get_width() // 2, window_height // 2))

        pygame.display.update()
```

This game_menu() function displays the menu options and waits for the player to press the Enter key to start the game. You can customize the menu appearance and add additional options as needed.

Add a call to the game_menu() function before the main game loop:
```py
game_menu()  # Call the game menu function

# Handling events and user input
running = True
clock = pygame.time.Clock()

while running:
    # Game logic and rendering graphics
    # ...
```

Place this call to game_menu() before the game loop to display the menu options and wait for the player to start the game.

By adding sound effects, customizing graphics, and implementing a game menu, you can significantly enhance the user experience of your Python snake game. Feel free to explore further improvements and features to make the game even more engaging and enjoyable!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p6mij4187bgn2ucqqgxb.png)


## Learning Python with an online Python compiler
Learning a new programming language might be intimidating if you're just starting out. Lightly IDE, however, makes learning Python simple and convenient for everybody. [Lightly IDE](https://www.lightly-dev.com/) was made so that even complete novices may get started writing code.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/du2fm8bvo79hrnwr5uch.png)


Lightly IDE's intuitive design is one of its many strong points. If you've never written any code before, don't worry; the interface is straightforward. You may quickly get started with Python programming with our [online Python compiler](https://www.lightly-dev.com/python/) only a few clicks.

The best part of Lightly IDE is that it is cloud-based, so your code and projects are always accessible from any device with an internet connection. You can keep studying and coding regardless of where you are at any given moment.

Lightly IDE is a great place to start if you're interested in learning Python. Learn and collaborate with other learners and developers on your projects and receive comments on your code now.

[Step-by-Step Guide to Build Python Snake Game with Pygame](https://www.lightly-dev.com/blog/build-python-snake-game-with-pygame/)