Building a Simple Snake Game with Python

Hello there, aspiring game developers and Python enthusiasts! Have you ever played the classic Snake game? It’s that wonderfully addictive game where you control a snake, eat food to grow longer, and avoid hitting walls or your own tail. It might seem like magic, but today, we’re going to demystify it and build our very own version using Python!

Don’t worry if you’re new to programming; we’ll break down each step using simple language and clear explanations. By the end of this guide, you’ll have a playable Snake game and a better understanding of some fundamental programming concepts. Let’s get started!

What You’ll Need

Before we dive into the code, let’s make sure you have everything ready.

  • Python: You’ll need Python installed on your computer. If you don’t have it, you can download it for free from the official Python website (python.org). We recommend Python 3.x.
  • A Text Editor: Any text editor will do (like VS Code, Sublime Text, Atom, or even Notepad++). This is where you’ll write your Python code.
  • The turtle module: Good news! Python comes with a built-in module called turtle that makes it super easy to draw graphics and create simple animations. We’ll be using this for our game’s visuals. You don’t need to install anything extra for turtle.
    • Supplementary Explanation: turtle module: Think of the turtle module as having a digital pen and a canvas. You can command a “turtle” (which looks like an arrow or a turtle shape) to move around the screen, drawing lines as it goes. It’s excellent for learning basic graphics programming.

Game Plan: How We’ll Build It

We’ll tackle our Snake game by breaking it down into manageable parts:

  1. Setting up the Game Window: Creating the screen where our game will live.
  2. The Snake’s Head: Drawing our main character and making it move.
  3. The Food: Creating something for our snake to eat.
  4. Controlling the Snake: Listening for keyboard presses to change the snake’s direction.
  5. Game Logic – The Main Loop: The heart of our game, where everything happens repeatedly.
    • Moving the snake.
    • Checking for collisions with food.
    • Making the snake grow.
    • Checking for collisions with walls or its own body (Game Over!).
  6. Scoring: Keeping track of how well you’re doing.

Let’s write some code!

Step 1: Setting Up the Game Window

First, we import the necessary modules and set up our game screen.

import turtle
import time
import random

wn = turtle.Screen() # This creates our game window
wn.setup(width=600, height=600) # Sets the size of the window to 600x600 pixels
wn.bgcolor("black") # Sets the background color of the window to black
wn.title("Simple Snake Game by YourName") # Gives our window a title
wn.tracer(0) # Turns off screen updates. We will manually update the screen later.
             # Supplementary Explanation: wn.tracer(0) makes the animation smoother.
             # Without it, you'd see the snake drawing itself pixel by pixel, which looks choppy.
             # wn.update() will be used to show everything we've drawn at once.

Step 2: Creating the Snake’s Head

Now, let’s draw our snake’s head and prepare it for movement.

head = turtle.Turtle() # Creates a new turtle object for the snake's head
head.speed(0) # Sets the animation speed to the fastest possible (0 means no animation delay)
head.shape("square") # Makes the turtle look like a square
head.color("green") # Sets the color of the square to green
head.penup() # Lifts the pen, so it doesn't draw lines when moving
             # Supplementary Explanation: penup() and pendown() are like lifting and putting down a pen.
             # When the pen is up, the turtle moves without drawing.
head.goto(0, 0) # Puts the snake head in the center of the screen (x=0, y=0)
head.direction = "stop" # A variable to store the snake's current direction

Step 3: Creating the Food

Our snake needs something to eat!

food = turtle.Turtle()
food.speed(0)
food.shape("circle") # The food will be a circle
food.color("red") # Red color for food
food.penup()
food.goto(0, 100) # Place the food at an initial position

Step 4: Adding the Scoreboard

We’ll use another turtle object to display the score.

score = 0
high_score = 0

pen = turtle.Turtle()
pen.speed(0)
pen.shape("square") # Shape doesn't matter much as it won't be visible
pen.color("white") # Text color
pen.penup()
pen.hideturtle() # Hides the turtle icon itself
pen.goto(0, 260) # Position for the score text (top of the screen)
pen.write(f"Score: {score} High Score: {high_score}", align="center", font=("Courier", 24, "normal"))
             # Supplementary Explanation: pen.write() displays text on the screen.
             # 'align' centers the text, and 'font' sets the style, size, and weight.

Step 5: Defining Movement Functions

These functions will change the head.direction based on keyboard input.

def go_up():
    if head.direction != "down": # Prevent the snake from reversing into itself
        head.direction = "up"

def go_down():
    if head.direction != "up":
        head.direction = "down"

def go_left():
    if head.direction != "right":
        head.direction = "left"

def go_right():
    if head.direction != "left":
        head.direction = "right"

def move():
    if head.direction == "up":
        y = head.ycor() # Get current y-coordinate
        head.sety(y + 20) # Move 20 pixels up

    if head.direction == "down":
        y = head.ycor()
        head.sety(y - 20) # Move 20 pixels down

    if head.direction == "left":
        x = head.xcor() # Get current x-coordinate
        head.setx(x - 20) # Move 20 pixels left

    if head.direction == "right":
        x = head.xcor()
        head.setx(x + 20) # Move 20 pixels right

Step 6: Keyboard Bindings

We need to tell the game to listen for key presses and call our movement functions.

wn.listen() # Tells the window to listen for keyboard input
wn.onkeypress(go_up, "w") # When 'w' is pressed, call go_up()
wn.onkeypress(go_down, "s") # When 's' is pressed, call go_down()
wn.onkeypress(go_left, "a") # When 'a' is pressed, call go_left()
wn.onkeypress(go_right, "d") # When 'd' is pressed, call go_right()

Step 7: The Main Game Loop (The Heart of the Game!)

This while True loop will run forever, updating the game state constantly. This is where all the magic happens! We’ll also need a list to keep track of the snake’s body segments.

segments = [] # An empty list to hold all the body segments of the snake

while True:
    wn.update() # Manually updates the screen. Shows all changes made since wn.tracer(0).

    # Check for collision with border
    if head.xcor() > 290 or head.xcor() < -290 or head.ycor() > 290 or head.ycor() < -290:
        time.sleep(1) # Pause for a second
        head.goto(0, 0) # Reset snake head to center
        head.direction = "stop"

        # Hide the segments
        for segment in segments:
            segment.goto(1000, 1000) # Move segments off-screen

        # Clear the segments list
        segments.clear() # Supplementary Explanation: segments.clear() removes all items from the list.

        # Reset the score
        score = 0
        pen.clear() # Clears the previous score text
        pen.write(f"Score: {score} High Score: {high_score}", align="center", font=("Courier", 24, "normal"))

    # Check for collision with food
    if head.distance(food) < 20: # Supplementary Explanation: .distance() calculates the distance between two turtles.
                                 # Our turtles are 20x20 pixels, so < 20 means they are overlapping.
        # Move the food to a random spot
        x = random.randint(-280, 280) # Random x-coordinate
        y = random.randint(-280, 280) # Random y-coordinate
        food.goto(x, y)

        # Add a new segment to the snake
        new_segment = turtle.Turtle()
        new_segment.speed(0)
        new_segment.shape("square")
        new_segment.color("grey") # Body segments are grey
        new_segment.penup()
        segments.append(new_segment) # Add the new segment to our list

        # Increase the score
        score += 10 # Add 10 points
        if score > high_score:
            high_score = score

        pen.clear() # Clear old score
        pen.write(f"Score: {score} High Score: {high_score}", align="center", font=("Courier", 24, "normal"))

    # Move the end segments first in reverse order
    # This logic makes the segments follow the head properly
    for index in range(len(segments) - 1, 0, -1):
        x = segments[index - 1].xcor()
        y = segments[index - 1].ycor()
        segments[index].goto(x, y)

    # Move segment 0 to where the head is
    if len(segments) > 0:
        x = head.xcor()
        y = head.ycor()
        segments[0].goto(x, y)

    move() # Call the move function to move the head

    # Check for head collision with the body segments
    for segment in segments:
        if segment.distance(head) < 20: # If head touches any body segment
            time.sleep(1)
            head.goto(0, 0)
            head.direction = "stop"

            # Hide the segments
            for seg in segments:
                seg.goto(1000, 1000)

            segments.clear()

            # Reset the score
            score = 0
            pen.clear()
            pen.write(f"Score: {score} High Score: {high_score}", align="center", font=("Courier", 24, "normal"))

    time.sleep(0.1) # Pause for a short time to control game speed
                    # Supplementary Explanation: time.sleep(0.1) makes the game run at a reasonable speed.
                    # A smaller number would make it faster, a larger number slower.

Running Your Game

To run your game, save the code in a file named snake_game.py (or any name ending with .py). Then, open your terminal or command prompt, navigate to the directory where you saved the file, and run it using:

python snake_game.py

A new window should pop up, and you can start playing your Snake game!

Congratulations!

You’ve just built a fully functional Snake game using Python and the turtle module! This project touches on many fundamental programming concepts:

  • Variables: Storing information like score, direction, coordinates.
  • Functions: Reusable blocks of code for movement and actions.
  • Lists: Storing multiple snake body segments.
  • Loops: The while True loop keeps the game running.
  • Conditional Statements (if): Checking for collisions, changing directions, updating score.
  • Event Handling: Responding to keyboard input.
  • Basic Graphics: Using turtle to draw and animate.

Feel proud of what you’ve accomplished! This is a fantastic stepping stone into game development and more complex Python projects.

What’s Next? (Ideas for Improvement)

This is just the beginning! Here are some ideas to expand your game:

  • Different Food Types: Add power-ups or different point values.
  • Game Over Screen: Instead of just resetting, display a “Game Over!” message.
  • Levels: Increase speed or introduce obstacles as the score goes up.
  • Sound Effects: Add sounds for eating food or game over.
  • GUI Libraries: Explore more advanced graphical user interface (GUI) libraries like Pygame or Kivy for richer graphics and more complex games.

Keep experimenting, keep learning, and most importantly, have fun coding!

Comments

Leave a Reply