Python Snake Game Tutorial for Beginners using Tkinter (Source Code)

Faraz

By Faraz - October 01, 2023

Learn Python game development from scratch with our beginner-friendly Snake Game tutorial. Get hands-on experience with source code and step-by-step guidance.


Python Snake Game Tutorial for Beginners using Tkinter.jpg

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Setting Up Your Environment
  4. Creating the Snake Game
  5. Full Source Code
  6. Explanation of Source Code
  7. Conclusion
  8. FAQs

1. Introduction

In this Python tutorial, we'll delve into the exciting world of game development by creating a simple yet addictive Snake game using the Tkinter library. Whether you're a novice programmer or just someone looking for a fun coding project, this tutorial is perfect for you. We'll guide you through the entire process, from setting up your development environment to adding the finishing touches to your game.

2. Prerequisites

Before we embark on this adventure, make sure you have the following prerequisites in place:

  • Basic knowledge of Python
  • Python installed on your computer
  • Tkinter library installed
  • Code editor (e.g., Visual Studio Code, PyCharm)

3. Setting Up Your Environment

Before we start coding the game, let's ensure you have everything set up correctly. Follow these steps:

  1. Install Python: If you haven't already, download and install Python from the official website (https://www.python.org/downloads/).
  2. Tkinter Installation: Tkinter usually comes pre-installed with Python, so you don't need to worry about this step. To check if Tkinter is available, open your Python IDLE and run the following command:
    import tkinter as tk
    If no errors occur, you're good to go.
  3. Code Editor: Choose a code editor of your preference and install it.

4. Creating the Snake Game

Step 1: Importing Libraries

Let's start by importing the necessary libraries for our game. Create a Python script and add the following lines:

from tkinter import *
import random

Step 2: Creating the Game Window

Now, let's create the game window using Tkinter. Set the window title:

window = Tk()
window.title("Snake Game")
window.resizable(False, False)

Step 3: Creating the Game Canvas

We'll draw the game elements with a canvas widget. Define the canvas and pack it into the window:

canvas = Canvas(window, bg=BACKGROUND_COLOUR,
                height=GAME_HEIGHT, width=GAME_WIDTH)
canvas.pack()

Step 4: Creating the Snake

Time to create our snake! We'll represent it as a list of rectangles. Start by defining the snake's initial position and size:

def __init__(self):
        self.body_size = BODY_PARTS
        self.coordinates = []
        self.squares = []

        for i in range(0, BODY_PARTS):
            self.coordinates.append([0, 0])

        for x, y in self.coordinates:
            square = canvas.create_rectangle(
                x, y, x + SPACE_SIZE, y + SPACE_SIZE, fill=SNAKE_COLOUR, tag="snake")
            self.squares.append(square)

Step 5: Creating the Food

Our snake needs something to eat! Generate random food on the canvas:

def __init__(self):

        x = random.randint(0, (GAME_WIDTH/SPACE_SIZE)-1) * SPACE_SIZE
        y = random.randint(0, (GAME_HEIGHT/SPACE_SIZE)-1) * SPACE_SIZE

        self.coordinates = [x, y]

        canvas.create_oval(x, y, x + SPACE_SIZE, y+SPACE_SIZE,
                           fill=FOOD_COLOUR, tag="food")

Step 6: Moving the Snake

Implement the logic for moving the snake and checking for collisions:

def next_turn(snake, food):
    
    x, y = snake.coordinates[0]

    if direction == 'up':
        y-=SPACE_SIZE
        
    elif direction == 'down':
        y+=SPACE_SIZE

    elif direction == 'left':
        x-=SPACE_SIZE

    elif direction == 'right':
        x+=SPACE_SIZE


    snake.coordinates.insert(0, (x,y))

    square = canvas.create_rectangle(x,y , x + SPACE_SIZE , y + SPACE_SIZE, fill=SNAKE_COLOUR)

    snake.squares.insert(0,square)

    if x==food.coordinates[0] and y == food.coordinates[1]:

        global score 
        
        score += 1

        label.config(text="Score: {}".format(score))

        canvas.delete("food")

        food = Food()

    else:
        del snake.coordinates[-1]

        canvas.delete(snake.squares[-1])

        del snake.squares[-1]

    if check_collisons(snake):
        game_over()

    else:
        window.after(SPEED,next_turn,snake,food)

Step 7: Checking for Collisions

Create functions to check if the snake collides with the wall, itself, or the food:

def check_collisons(snake):
    x , y = snake.coordinates[0]

    if x < 0 or x >= GAME_WIDTH:
        return True
    elif y < 0 or y >= GAME_HEIGHT:
        return True
    
    for body_part in snake.coordinates[1:]:
        if x == body_part[0] and y == body_part[1]:
            return True
        
    return False

5. Full Source Code

from tkinter import *
import random

GAME_WIDTH = 600
GAME_HEIGHT = 600
SPEED = 90
SPACE_SIZE = 50
BODY_PARTS = 3
SNAKE_COLOUR = "#00FF00"
FOOD_COLOUR = "#FF0000"
BACKGROUND_COLOUR = "#000000"

class Snake:

    def __init__(self):
        self.body_size = BODY_PARTS
        self.coordinates = []
        self.squares =[]

        for i in range (0, BODY_PARTS):
            self.coordinates.append([0,0])

        for x,y in self.coordinates:
            square = canvas.create_rectangle(x, y, x + SPACE_SIZE , y + SPACE_SIZE , fill=SNAKE_COLOUR, tag = "snake")
            self.squares.append(square)


class Food:
    
    def __init__(self):

        x= random.randint(0,(GAME_WIDTH/SPACE_SIZE)-1)* SPACE_SIZE
        y= random.randint(0,(GAME_HEIGHT/SPACE_SIZE)-1)* SPACE_SIZE

        self.coordinates = [x,y]

        canvas.create_oval(x, y, x+ SPACE_SIZE, y+SPACE_SIZE, fill=FOOD_COLOUR, tag="food")



def next_turn(snake, food):
    
    x, y = snake.coordinates[0]

    if direction == 'up':
        y-=SPACE_SIZE
        
    elif direction == 'down':
        y+=SPACE_SIZE

    elif direction == 'left':
        x-=SPACE_SIZE

    elif direction == 'right':
        x+=SPACE_SIZE


    snake.coordinates.insert(0, (x,y))

    square = canvas.create_rectangle(x,y , x + SPACE_SIZE , y + SPACE_SIZE, fill=SNAKE_COLOUR)

    snake.squares.insert(0,square)

    if x==food.coordinates[0] and y == food.coordinates[1]:

        global score 
        
        score += 1

        label.config(text="Score: {}".format(score))

        canvas.delete("food")

        food = Food()

    else:
        del snake.coordinates[-1]

        canvas.delete(snake.squares[-1])

        del snake.squares[-1]

    if check_collisons(snake):
        game_over()

    else:
        window.after(SPEED,next_turn,snake,food)


def change_direction(new_direction):

    global direction 

    if new_direction =='left':
        if direction!= 'right':
            direction = new_direction

    elif new_direction == 'right':
        if direction!= 'left':
            direction = new_direction

    if new_direction =='up':
        if direction!= 'down':
            direction = new_direction

    if new_direction =='down':
        if direction!= 'up':
            direction = new_direction


def check_collisons(snake):
    x , y = snake.coordinates[0]

    if x < 0 or x >= GAME_WIDTH:
        return True
    elif y < 0 or y >= GAME_HEIGHT:
        return True
    
    for body_part in snake.coordinates[1:]:
        if x == body_part[0] and y == body_part[1]:
            return True
        
    return False

def  game_over():
    # canvas.delete(ALL)
    canvas.create_text(canvas.winfo_width()/2, canvas.winfo_height()/2, font=('consolas',70),text="GAME OVER", fill="red", tag = "gameover")


    reset_button = Button(text = "Restart", font=('consolas',20),command = reset)
    canvas.create_window(300,400,window=reset_button)

def reset():
    score = 0
    label.config(text="Score:{}".format(score))
    canvas.delete(ALL)

    snake = Snake()
    food = Food()
    next_turn(snake,food)
    


window = Tk()
window.title("Snake Game")
window.resizable(False,False)

score = 0
direction = 'down'

label = Label(window, text="Score:{}".format(score),font=('consolas',40))
label.pack()

canvas = Canvas(window, bg= BACKGROUND_COLOUR,height=GAME_HEIGHT,width=GAME_WIDTH )
canvas.pack()

window.bind('<Left>',lambda event: change_direction('left'))
window.bind('<Right>',lambda event: change_direction('right'))
window.bind('<Up>',lambda event: change_direction('up'))
window.bind('<Down>',lambda event: change_direction('down'))

snake = Snake()

food =Food()

next_turn(snake,food)

window.mainloop()

6. Explanation of Source Code

Here's an explanation of the code:

Importing necessary libraries:

  • from tkinter import *: Imports the entire tkinter library for creating GUI elements.
  • import random: Imports the random module for generating random numbers.

Constants and Global Variables:

  • Several constants and global variables are defined at the beginning of the code, specifying attributes of the game such as dimensions, speed, colors, and more.

Snake Class:

  • The Snake class is defined to represent the snake in the game.
  • It initializes with the snake's size, coordinates, and squares (the individual segments of the snake).
  • The snake's initial coordinates are set to (0, 0) for each segment.
  • The create_rectangle method from the tkinter canvas is used to create each square of the snake, and these squares are stored in the self.squares list.

Food Class:

  • The Food class is defined to represent the food that the snake must eat.
  • It initializes with random x and y coordinates within the game boundaries, and these coordinates are stored in the self.coordinates.
  • An oval shape is created using create_oval from tkinter to represent the food on the canvas.

next_turn Function:

  • This function is called to update the game state after each turn.
  • It calculates the new head position of the snake based on the current direction.
  • If the snake eats the food, the score is incremented, and new food is generated.
  • The function also removes the tail of the snake to maintain its size.
  • It checks for collisions with boundaries or itself using the check_collisions function.
  • If a collision is detected, it triggers the game_over function.
  • Otherwise, it schedules the next turn after a delay defined by SPEED.

change_direction Function:

  • This function is called when the player presses arrow keys to change the snake's direction.
  • It updates the direction global variable but prevents the snake from reversing its direction.

check_collisions Function:

  • This function checks for collisions between the snake and the boundaries of the game window or itself.
  • It returns True if there's a collision and False otherwise.

game_over Function:

  • This function is called when the game is over (i.e., when the snake collides with a boundary or itself).
  • It displays a "GAME OVER" message in the center of the canvas and a "Restart" button to start a new game.

reset Function:

  • This function resets the game when the "Restart" button is clicked.
  • It resets the score, clears the canvas, creates a new snake and food, and starts a new game.

Main Code:

  • The main code initializes the tkinter window, sets up event bindings for arrow keys to change the snake's direction, and creates the initial snake and food.
  • The game loop is started with window.mainloop(), which keeps the game running until the window is closed.

7. Conclusion

Congratulations! You've completed your first Python Snake Game using Tkinter. You've learned how to set up your environment, create a game window, handle user input, and manage game elements. Now, it's time to unleash your creativity and enhance the game further. Happy coding!

8. FAQs

1. Can I customize the snake's and food's appearance in the game?

Yes, you can modify the corresponding code by modifying the colors and shapes of the snake and food.

2. How can I increase the game's difficulty?

You can make the game more challenging by increasing the snake's speed or adding obstacles to the canvas.

3. Is it possible to add sound effects to the game?

Absolutely! You can incorporate sound effects by using Python libraries like Pygame.

4. Can I make the game multiplayer?

Expanding the game to include multiplayer functionality would be an advanced project, but it's definitely possible with additional coding.

5. Where can I find more Python game development resources?

You can explore online tutorials, forums, and communities dedicated to game development to learn more and find inspiration for your next project.

That’s a wrap!

I hope you enjoyed this article

Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee.

And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!

Thanks!
Faraz 😊

End of the article

Subscribe to my Newsletter

Get the latest posts delivered right to your inbox


Latest Post