Building a snake game in Python using the pygame framework.

In this article, you will learn how to build a pygame snake game using Python pygame framework. you will write a complete code for the snake game in Python. pygame framework is a collection of a set of Python modules developed on the top of the SDL library. This tutorial is for beginners on how to create a game using Python.

To make a game in Python, the first step is to create a project using your favorite Python IDE like pycharm or visual studio code and create a virtual environment I will be using visual studio code for this snake game project.

Creating a snake game project in visual studio code

Before starting to create a game first create a folder snake_project, create a virtual environment using pip and open the folder with the visual studio code as shown below.

Creating a folder structure and virtual environment

  1. First, create a project folder snake_project
  2. Create a virtual environment in Python using virtualenv command, if virtualenv command is not available, you need to install the virtualenv package using pip install virtualenv
  3. Open your project with code command in vs code
# Navigate to desktop 
cd C:\users\user\Desktop\

# Create a snake_project folder
mkdir snake_project
cd snake_project

# Create virtual environment 
virtualenv venv

Open Project in Vscode

To open your project with vs code navigate to your project folder right click and click Open with Code menu to open your project in visual studio code.

Building a snake game in Python using the pygame framework. snake game in python

Install pygame

To build the snake game we will need to install pygame in our project, to install pygame use the following command below:

pip install pygame

Start building the snake game

To start building the snake game first you need to create a game file, create snake.py python file inside your project folder as shown below.

Building a snake game in Python using the pygame framework. snake game in python
snake game starting file

Now we have a game file, below is the step-by-step process that you will write in snake.py file to build a snake game

Step 1: Import pygame and initialize the game.

In this step, we import pygame and random module into our project.

We also initialize the game by calling pygame.init() from the pygame module and also define the required variables SCREEN_WIDTH and SCREEN_HEIGHT to define the size of the game screen in pixels, while BLOCK_SIZE sets the size of the individual blocks or “pixels” of the snake. SNAKE_SPEED determines how fast the snake moves.

Code

import pygame, random

pygame.init()
SCREEN_WIDTH, SCREEN_HEIGHT = 600, 400
BLOCK_SIZE = 10
SNAKE_SPEED = 15

Step 2: Create the Screen

As we have already defined the screen width and size above, to create a screen in Pygame, we will need to make use of the display.set_mode() function from pygame.

Additionally, we will need to use quit() methods to uninitialized everything at end of the program.

To update any changes made to the screen, we can use either the update() or the flip() method. The update() method only updates the changes made to the screen, or updates the entire screen if no parameters are passed. In contrast, the flip() method updates the entire screen.

import pygame, random

pygame.init()

SCREEN_WIDTH, SCREEN_HEIGHT = 600, 400
BLOCK_SIZE = 10
SNAKE_SPEED = 15
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Snake Game by tutcoach')
pygame.display.update()

# Quit the game
pygame.quit()

When you try to run the above code, a blank screen will appear and disappear immediately, it is because, for a game to run in a continuous mode, we need to define a game loop.

Step 3: Define clock

Now in this, we need to configure a game clock using pygame.time.Clock() class, the clock object is used to control the frame rate of a game by calling a tick method on the clock object at the end of every game loop so that the game runs at a constant frame rate regardless of the processing power of the computer in which the game is running.

import pygame, random

pygame.init()

SCREEN_WIDTH, SCREEN_HEIGHT = 600, 400
BLOCK_SIZE = 10
SNAKE_SPEED = 15

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Snake Game')

clock = pygame.time.Clock()

Step 4: Define Display font style

In this step, we will create a Pygame Font object using the pygame.font.SysFont() function, SysFont() the function is used to render the text in our game window.

This code creates a. The SysFont() function creates a Font object that can be used to render text onto the Pygame window.

import pygame, random

pygame.init()

SCREEN_WIDTH, SCREEN_HEIGHT = 600, 400
BLOCK_SIZE = 10
SNAKE_SPEED = 15

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Snake Game')

clock = pygame.time.Clock()
font = pygame.font.SysFont("Arial", 25)

The font size argument specifies the size of the font in pixels. In this example, the font size is set to 25 pixels.

Step 5: Draw a snake

To draw a snake we will define a draw_snake function.

The draw_snake function takes a list of coordinates called snake_list as its argument.

Here draw_snake function iterates through each block in the snake_list using a for loop. For each block, we uses the pygame.draw.rect() function to draw a rectangle on the Pygame window.

The pygame.draw.rect() function takes three arguments:

  • The screen argument specifies the surface to draw the rectangle on.
  • The (0, 0, 0) argument specifies the color of the rectangle. In this case, the color is black because the tuple (0, 0, 0) represents black in the RGB color model.
  • The [block[0], block[1], BLOCK_SIZE, BLOCK_SIZE] argument specifies the dimensions of the rectangle. The first two elements of the list (block[0] and block[1]) specify the x and y coordinates of the top-left corner of the rectangle, and the last two elements (BLOCK_SIZE) specify the width and height of the rectangle.

By calling this function on each iteration of the game loop with the current snake_list, the function will draw the entire snake on the Pygame window.

import pygame, random

pygame.init()

SCREEN_WIDTH, SCREEN_HEIGHT = 600, 400
BLOCK_SIZE = 10
SNAKE_SPEED = 15

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Snake Game')

clock = pygame.time.Clock()
font = pygame.font.SysFont("bahnschrift", 25)

def draw_snake(snake_list):
    for block in snake_list:
        pygame.draw.rect(screen, (0, 0, 0), [block[0], block[1], BLOCK_SIZE, BLOCK_SIZE])

Step 6: Display the message on snake game screen

In this step we will define a function called message that takes two arguments: text and color. Inside this function we use the font.render() to render a text in screen. The text argument is the string that is to be rendered and the True argument indicates that anti-aliasing should be applied to the text, here anti-aliasing means drawing smooth edges of the text for a better visual appearance.

The color argument is a tuple that specifies the color of the text. The resulting Surface object will have the rendered text with the specified color.

we have used screen.blit() function to draw the Surface object onto the Pygame window. The first argument is the Surface object that is to be drawn and the second argument specifies the position on the screen where the Surface object should be drawn at the position [SCREEN_WIDTH / 6, SCREEN_HEIGHT / 3], which is one-sixth of the way across the width of the screen and one-third of the way down the height of the screen.

def message(text, color):
    message = font.render(text, True, color)
    screen.blit(message, [SCREEN_WIDTH / 6, SCREEN_HEIGHT / 3])

up to now, the complete code looks like

import pygame, random

pygame.init()

SCREEN_WIDTH, SCREEN_HEIGHT = 600, 400
BLOCK_SIZE = 10
SNAKE_SPEED = 15

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Snake Game')

clock = pygame.time.Clock()
font = pygame.font.SysFont("bahnschrift", 25)

def draw_snake(snake_list):
    for block in snake_list:
        pygame.draw.rect(screen, (0, 0, 0), [block[0], block[1], BLOCK_SIZE, BLOCK_SIZE])

def message(text, color):
    message = font.render(text, True, color)
    screen.blit(message, [SCREEN_WIDTH / 6, SCREEN_HEIGHT / 3])

Step 7: Define game loop

def game_loop():
    game_over = False
    x, y = SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2
    x_change, y_change = 0, 0
    snake_list = []
    snake_length = 1
    foodx, foody = round(random.randrange(0, SCREEN_WIDTH - BLOCK_SIZE) / 10.0) * 10.0, round(random.randrange(0, SCREEN_HEIGHT - BLOCK_SIZE) / 10.0) * 10.0

    while not game_over:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game_over = True
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    x_change, y_change = -BLOCK_SIZE, 0
                elif event.key == pygame.K_RIGHT:
                    x_change, y_change = BLOCK_SIZE, 0
                elif event.key == pygame.K_UP:
                    x_change, y_change = 0, -BLOCK_SIZE
                elif event.key == pygame.K_DOWN:
                    x_change, y_change = 0, BLOCK_SIZE

        if x >= SCREEN_WIDTH or x < 0 or y >= SCREEN_HEIGHT or y < 0:
            game_over = True
        x += x_change
        y += y_change

        screen.fill((50, 153, 213))
        pygame.draw.rect(screen, (0, 255, 0), [foodx, foody, BLOCK_SIZE, BLOCK_SIZE])
        snake_head = []
        snake_head.append(x)
        snake_head.append(y)
        snake_list.append(snake_head)
        if len(snake_list) > snake_length:
            del snake_list[0]

        for block in snake_list[:-1]:
            if block == snake_head:
                game_over = True

        draw_snake(snake_list)
        pygame.display.update()

        if x == foodx and y == foody:
            foodx, foody = round(random.randrange(0, SCREEN_WIDTH - BLOCK_SIZE) / 10.0) * 10.0, round(random.randrange(0, SCREEN_HEIGHT - BLOCK_SIZE) / 10.0) * 10.0
            snake_length += 1

        clock.tick(SNAKE_SPEED)

    pygame.quit()
    quit()

Here the step-by-step explanation of the above code is our game loop

  1. def game_loop() function called game_loop which will contain the code for running the game.
  2. game_over = False – Set a boolean variable game_over to False, which will be used to control the game loop.
  3. x, y = SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 – Set the initial position of the snake’s head to be in the center of the screen.
  4. x_change, y_change = 0, 0 – Set the initial speed of the snake to be zero in both x and y directions.
  5. snake_list = [] – Create an empty list to store the coordinates of each block of the snake.
  6. snake_length = 1 – Initialize the length of the snake to be 1.
  7. foodx, foody = round(random.randrange(0, SCREEN_WIDTH - BLOCK_SIZE) / 10.0) * 10.0, round(random.randrange(0, SCREEN_HEIGHT - BLOCK_SIZE) / 10.0) * 10.0 – Generate a random location for the food.
  8. while not game_over: – Start the main game loop. This will continue until the game_over variable is set to True.
  9. for event in pygame.event.get(): – Loop through all the events that have occurred since the last iteration of the loop.
  10. if event.type == pygame.QUIT: – If the user clicks the “close” button on the game window, set game_over to True.
  11. if event.type == pygame.KEYDOWN: – If the user presses a key on the keyboard, check which key was pressed and change the snake’s direction accordingly.
  12. if x >= SCREEN_WIDTH or x < 0 or y >= SCREEN_HEIGHT or y < 0: – Check if the snake has hit a wall (i.e. gone out of bounds), and if so, set game_over to True.
  13. x += x_change and y += y_change – Update the position of the snake’s head based on its speed.
  14. screen.fill((50, 153, 213)) – Fill the screen with a light blue color.
  15. pygame.draw.rect(screen, (0, 255, 0), [foodx, foody, BLOCK_SIZE, BLOCK_SIZE]) – Draw the food on the screen as a green square.
  16. snake_head = [] – Create an empty list to store the coordinates of the snake’s head.
  17. snake_head.append(x) and snake_head.append(y) – Add the current position of the snake’s head to the snake_head list.
  18. snake_list.append(snake_head) – Add the snake_head list to the snake_list list to store the position of the snake’s head.
  19. if len(snake_list) > snake_length: and del snake_list[0] – If the length of the snake_list is greater than snake_length, remove the first block of the snake (i.e. the tail).
  20. for block in snake_list[:-1]: – Loop through all the blocks of the snake except the head.
  21. if block == snake_head: – If the head of the snake collides with any of its body parts, set game_over to True.
  22. draw_snake(snake_list)
  23. pygame.display.update() is a function in the Pygame library that updates the full display surface to the screen. It refreshes the entire screen or a part of the screen that has been changed. It is important to call pygame.display.update() in order to update the display surface with the changes made to the game will playing. Without this function, the changes will not be visible on the screen.
  24. if x == foodx and y == foody: – Checks if the snake’s head has collided with the food block.
  25. foodx, foody = round(random.randrange(0, SCREEN_WIDTH - BLOCK_SIZE) / 10.0) * 10.0, round(random.randrange(0, SCREEN_HEIGHT - BLOCK_SIZE) / 10.0) * 10.0 – If the snake’s head has collided with the food block, generate a new set of coordinates for the food block.
  26. snake_length += 1 – Increase the length of the snake by one unit.
  27. clock.tick(SNAKE_SPEED) – Wait for the amount of time specified in the SNAKE_SPEED constant.
  28. pygame.quit() – Uninitialize all pygame modules.
  29. quit() – Quit the program.
  30. game_loop() – Call the game_loop() function to start the game loop again. This ensures that the game keeps running until the user quits.

Final pygame snake code

Here is the final code of our pygame snake game

import pygame, random

pygame.init()

SCREEN_WIDTH, SCREEN_HEIGHT = 600, 400
BLOCK_SIZE = 10
SNAKE_SPEED = 15

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Snake Game')

clock = pygame.time.Clock()
font = pygame.font.SysFont("bahnschrift", 25)

def draw_snake(snake_list):
    for block in snake_list:
        pygame.draw.rect(screen, (0, 0, 0), [block[0], block[1], BLOCK_SIZE, BLOCK_SIZE])

def message(text, color):
    message = font.render(text, True, color)
    screen.blit(message, [SCREEN_WIDTH / 6, SCREEN_HEIGHT / 3])

def game_loop():
    game_over = False
    x, y = SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2
    x_change, y_change = 0, 0
    snake_list = []
    snake_length = 1
    foodx, foody = round(random.randrange(0, SCREEN_WIDTH - BLOCK_SIZE) / 10.0) * 10.0, round(random.randrange(0, SCREEN_HEIGHT - BLOCK_SIZE) / 10.0) * 10.0

    while not game_over:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game_over = True
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    x_change, y_change = -BLOCK_SIZE, 0
                elif event.key == pygame.K_RIGHT:
                    x_change, y_change = BLOCK_SIZE, 0
                elif event.key == pygame.K_UP:
                    x_change, y_change = 0, -BLOCK_SIZE
                elif event.key == pygame.K_DOWN:
                    x_change, y_change = 0, BLOCK_SIZE

        if x >= SCREEN_WIDTH or x < 0 or y >= SCREEN_HEIGHT or y < 0:
            game_over = True
        x += x_change
        y += y_change

        screen.fill((50, 153, 213))
        pygame.draw.rect(screen, (0, 255, 0), [foodx, foody, BLOCK_SIZE, BLOCK_SIZE])
        snake_head = []
        snake_head.append(x)
        snake_head.append(y)
        snake_list.append(snake_head)
        if len(snake_list) > snake_length:
            del snake_list[0]

        for block in snake_list[:-1]:
            if block == snake_head:
                game_over = True

        draw_snake(snake_list)
        pygame.display.update()

        if x == foodx and y == foody:
            foodx, foody = round(random.randrange(0, SCREEN_WIDTH - BLOCK_SIZE) / 10.0) * 10.0, round(random.randrange(0, SCREEN_HEIGHT - BLOCK_SIZE) / 10.0) * 10.0
            snake_length += 1

        clock.tick(SNAKE_SPEED)

    pygame.quit()
    quit()

game_loop()

Running pygame snake game

once you run your game the output of the pygame as shown below

Building a snake game in Python using the pygame framework. snake game in python

Leave a Comment