Snake Game in Python with Pygame

Robson Sampaio
6 min readMay 24, 2020

Hi, this article will show you how to build your own snake game with python. I tried to make it as simple as I could to make the tutorial shorter. So let’s get to the game.

The game

Before we get our hands dirty we have to decide a few rules to the snake game that we are about to code.

  1. The snake cannot hit the walls;
  2. The snake cannot hit itself;
  3. The snake gets bigger and faster when it eats apples.

Creating the arena

Yeah, lets start by creating the main screen. The Pygame library really made life a lot simpler, so first of all you have to install pygame. If you do not have pip installed I strongly recommend you do it.

pip install pygame

and then …

With this script you will be able to visualize your first screen. And here it comes a simple explanation of the code.

GAME_ON = True

GAME_ON is the control variable, if it is true the game is on, if not you will quit the game.

pygame.display.set_mode((400,400))

Here we set the screen size with a tuple (400, 400). If you want you can create a variable to storage the tuple it’s up to you.

In order to be able to get events I put this code inside the while loop.

for event in pygame.event.get():
if event.type == QUIT:
GAME_ON = False

This part search for every event such as mouse click or the key board being hit and so on. So here is the screen:

I know it does no look much, but be patient young padawan.

The Snake

Now that we already have our screen, lets create our snake. For that I decided to create another file called snake.py

Well, if you are familiar with python and OOP you will see that I just created a class called Snake and also created a constructor which is the method __init__

Inside the __init__ I set the snake by using a array of tuple, each index relates to a part of the snake body. I created the snake skin with the Surface class. To create a Surface you need at minimum it’s size, which is a tuple (x, y), representing the size in pixels. You could also set the path to an image, but we won’t be dealing with images in this tutorial.

Well, because I wanted the snake to have some colorI used the pygame.fill() function to set a white color to all the skin.

Now lets put the snake inside the game.

Out of the loop I created the snake object. Inside the loop I had to get every part of the snake with a for loop and put it into the screen. The blit function is enough to do the job. It puts a Surface above another. Finally I update the display to see the changes.

Well, I think we should set a head to our snake, so let’s do it.

self.head = pygame.Surface((10,10))
self.head.fill((200, 200, 200))

Inside the Snake class insert the above code. We are just creating the head surface and filling it with some gray color. Now we have to insert this surface to the game.

for snake_pos in snake.snake[0:-1]:
screen.blit(snake.skin, snake_pos)
screen.blit(snake.head, snake.snake[-1])

So basically I am saying that the for loop has to go until the penult index and and use the blit function with the skin. When the for loops and it will use blit to insert the head surface with the last index.

Now our snake has a head. Yeah, I know, it looks like a cigarrete.

Our cigarrete, …, I mean, our snake was created, now lets make it move around.

First we have to create a method in snake.py that can make the snake walk (or crawl, run or whatever the snake does)

So if you well remember our snake is basically a array of tuples. So if we want it to walk we just have to append new tuple to the head and pop out from the first index. I also had to set directions (UP, DOWN, LEFT, RITGH). So if the snake is going to the RIGH or LEFT I have to append a new position in the x-axis. If the snake is going UP or DOWN it will append to the y-axis.

Now I will have to detect som keyboard events

The events detect what key I have hit and then changes the snake directions. By default the snake goes to the right. I also had to avoid the snake to run over itself in case you hit UP and the snake was going DOWN and the same goes for the right and left. So the snake can never go the opposite direction.

To slow down the snake I used the clock.tick method with a default SPEED of 10. The speed will increase as the snakes eats apples.

Now our snake can move!

Well, I think it is time to create the apple

The Apple

As we did with the snake lets create a new file called apple.py.

Well nothing new here but the set_random_position method. Let’s go to the game.py and se what changed.

apple = Apple()
apple.set_random_position(400)

Out of the loop I created the apple object and set its position by sending the screen size.

screen.fill((0,0,0))
for snake_pos in snake.snake[0:-1]:
screen.blit(snake.skin, snake_pos)
screen.blit(snake.head, snake.snake[-1])
screen.blit(apple.apple, apple.position)

Inside the loop I just added the apple with the blit method.

But wait! Our snake can’t eat the apple yet. We haven’t created a method to allow it. Let’s do it!

The game functionalities

The idea is very simple, whenever the snake’s head reachs the apple’s position we will change the apple position with the set_random_position method and we also have to increment one more block to the snake and increase SPEED.

def snake_eat_apple(self, apple_pos):
return self.snake[-1] == apple_pos

def snake_bigger(self):
self.snake.insert(0, (self.snake[0]))

In the Snake class I created two new methods:

  • snake_eat_apple: it will return true if the head of the snake is in the same position as the apple
  • snake_bigger: it will insert a part of the snake to its own body
if snake.snake_eat_apple(apple.position):
apple.set_random_position(400)
snake.snake_bigger()
SPEED += 0.5

As I said, in the game.py inside the loop I ask if snake_eat_apple returns true, if it does it will change the apple position, increase the size of the snake and increase speed

We are almost done! Now lets implement the method to check if the snake hits the wall or run over itself.

To detect if the snake runs over itself you just have to check if the snake’s head position is inside is own body, in python it is a really easy implementation.

the wall_collision return true if the snake out run the screen

if snake.wall_collision(400) or snake.self_collision():
GAME_ON = False

Inside the loop in game.py I just had to implement a if statment to check if any of those functions return true, if they do GAME_ON is set to false and then GAME OVER!

Let me see the code

game.py

snake.py

apple.py

What have I done?!

I’ve just created you own snake game! Congrats!

But there is still work to do

If you play it enough you will that it has a bug (or bugs) to be fixed. For example

  • If you hit the directions buttons too fast you might send two events at the same time making the snake to run over itself when it should not.

You could also implement more features such as:

  • Insert a score board
  • Make the apple disapear after some time
  • create walls inside the arena to make the game harder
  • Insert a game over screen
  • Create a pause function

See you in the next tutorial

I hope you have enjoyed this tutorial, keep up with your studies and Let’s Code!

--

--

Robson Sampaio
0 Followers

Full stack developer and researcher. #react-native #react #nodejs #python #IoT #EmbeddedSystems