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.
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.
Before we embark on this adventure, make sure you have the following prerequisites in place:
Before we start coding the game, let's ensure you have everything set up correctly. Follow these steps:
import tkinter as tkIf no errors occur, you're good to go.
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
Now, let's create the game window using Tkinter. Set the window title:
window = Tk() window.title("Snake Game") window.resizable(False, False)
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()
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)
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")
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)
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
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()
Here's an explanation of the code:
Importing necessary libraries:
Constants and Global Variables:
Snake Class:
Food Class:
next_turn Function:
change_direction Function:
check_collisions Function:
game_over Function:
reset Function:
Main Code:
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!
Yes, you can modify the corresponding code by modifying the colors and shapes of the snake and food.
You can make the game more challenging by increasing the snake's speed or adding obstacles to the canvas.
Absolutely! You can incorporate sound effects by using Python libraries like Pygame.
Expanding the game to include multiplayer functionality would be an advanced project, but it's definitely possible with additional coding.
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 😊