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
- First, create a project folder
snake_project
- Create a virtual environment in Python using
virtualenv
command, ifvirtualenv
command is not available, you need to install the virtualenv package usingpip install virtualenv
- 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.
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.
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]
andblock[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
def game_loop()
function calledgame_loop
which will contain the code for running the game.game_over = False
– Set a boolean variablegame_over
toFalse
, which will be used to control the game loop.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.x_change, y_change = 0, 0
– Set the initial speed of the snake to be zero in both x and y directions.snake_list = []
– Create an empty list to store the coordinates of each block of the snake.snake_length = 1
– Initialize the length of the snake to be 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
– Generate a random location for the food.while not game_over:
– Start the main game loop. This will continue until thegame_over
variable is set toTrue
.for event in pygame.event.get():
– Loop through all the events that have occurred since the last iteration of the loop.if event.type == pygame.QUIT:
– If the user clicks the “close” button on the game window, setgame_over
toTrue
.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.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, setgame_over
toTrue
.x += x_change
andy += y_change
– Update the position of the snake’s head based on its speed.screen.fill((50, 153, 213))
– Fill the screen with a light blue color.pygame.draw.rect(screen, (0, 255, 0), [foodx, foody, BLOCK_SIZE, BLOCK_SIZE])
– Draw the food on the screen as a green square.snake_head = []
– Create an empty list to store the coordinates of the snake’s head.snake_head.append(x)
andsnake_head.append(y)
– Add the current position of the snake’s head to thesnake_head
list.snake_list.append(snake_head)
– Add thesnake_head
list to thesnake_list
list to store the position of the snake’s head.if len(snake_list) > snake_length:
anddel snake_list[0]
– If the length of thesnake_list
is greater thansnake_length
, remove the first block of the snake (i.e. the tail).for block in snake_list[:-1]:
– Loop through all the blocks of the snake except the head.if block == snake_head:
– If the head of the snake collides with any of its body parts, setgame_over
toTrue
.draw_snake(snake_list)
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 callpygame.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.if x == foodx and y == foody:
– Checks if the snake’s head has collided with the food block.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.snake_length += 1
– Increase the length of the snake by one unit.clock.tick(SNAKE_SPEED)
– Wait for the amount of time specified in theSNAKE_SPEED
constant.pygame.quit()
– Uninitialize all pygame modules.quit()
– Quit the program.game_loop()
– Call thegame_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