๐ŸŽ“ A1Learner
๐Ÿ”
0 of 18 lessons completed

Python Snake Colours and a Border

A colour scheme gives each part of the game its own colour. A border drawn on the board now shows the wall line as a white square.

A dark green board

The window setup paints the whole board with one colour name. The name darkgreen goes to bgcolor as a plain word.

# The game window
screen = turtle.Screen()
screen.setup(width=600, height=600)
screen.bgcolor("darkgreen")
screen.title("Snake")
screen.tracer(0)

The border turtle

The border is a Turtle of its own. It lifts its pen, moves to one corner, and then puts the pen down.

# The border marks the edge of the board
border = turtle.Turtle()
border.speed(0)
border.color("white")
border.penup()
border.goto(-290, -290)
border.pendown()

Four sides make a square

One forward call walks a full side of the board. One left turn aims the turtle along the next side.

for side in range(4):
    border.forward(580)
    border.left(90)
border.hideturtle()

A lime head

The head sets its colour with the word lime. Its pen stays up, so the head itself draws no line.

# The snake head
head = turtle.Turtle()
head.speed(0)
head.shape("square")
head.color("lime")
head.penup()
head.goto(0, 0)
head.direction = "right"

A light green body

Each new segment sets its colour with the word lightgreen. The segment lines up behind the head on the next tick.

            new_segment = turtle.Turtle()
            new_segment.speed(0)
            new_segment.shape("square")
            new_segment.color("lightgreen")
            new_segment.penup()

Example

import turtle
import time
import random

# The game window
screen = turtle.Screen()
screen.setup(width=600, height=600)
screen.bgcolor("darkgreen")
screen.title("Snake")
screen.tracer(0)

# The border marks the edge of the board
border = turtle.Turtle()
border.speed(0)
border.color("white")
border.penup()
border.goto(-290, -290)
border.pendown()
for side in range(4):
    border.forward(580)
    border.left(90)
border.hideturtle()

# The snake head
head = turtle.Turtle()
head.speed(0)
head.shape("square")
head.color("lime")
head.penup()
head.goto(0, 0)
head.direction = "right"

# The food: one red circle on the board
food = turtle.Turtle()
food.speed(0)
food.shape("circle")
food.color("red")
food.penup()

# The body starts empty; the scores start at zero
segments = []
score = 0
high_score = 0
delay = 0.1
paused = False

# The pen writes the score at the top of the board
pen = turtle.Turtle()
pen.speed(0)
pen.color("white")
pen.penup()
pen.hideturtle()
pen.goto(0, 260)


def move():
    if head.direction == "up":
        head.sety(head.ycor() + 20)
    if head.direction == "down":
        head.sety(head.ycor() - 20)
    if head.direction == "left":
        head.setx(head.xcor() - 20)
    if head.direction == "right":
        head.setx(head.xcor() + 20)


def go_up():
    if head.direction != "down":
        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 new_food_spot():
    x = random.randint(-14, 14) * 20
    y = random.randint(-14, 14) * 20
    food.goto(x, y)


def show_score():
    pen.clear()
    pen.write(f"Score: {score}  High Score: {high_score}", align="center", font=("Courier", 20, "bold"))


def toggle_pause():
    global paused
    paused = not paused


def reset_game():
    global score, high_score, delay
    time.sleep(0.5)
    head.goto(0, 0)
    head.direction = "stop"
    for segment in segments:
        segment.hideturtle()
    segments.clear()
    if score > high_score:
        high_score = score
    score = 0
    delay = 0.1
    show_score()


new_food_spot()
show_score()

# The keyboard steers the snake
screen.listen()
screen.onkey(go_up, "Up")
screen.onkey(go_down, "Down")
screen.onkey(go_left, "Left")
screen.onkey(go_right, "Right")
screen.onkey(toggle_pause, "p")
screen.onkey(reset_game, "r")

# The game loop: redraw, step the game unless paused, wait, repeat
while True:
    screen.update()

    if not paused:
        # The body follows: each segment takes the place of the one ahead
        for index in range(len(segments) - 1, 0, -1):
            x = segments[index - 1].xcor()
            y = segments[index - 1].ycor()
            segments[index].goto(x, y)
        if len(segments) > 0:
            segments[0].goto(head.xcor(), head.ycor())

        move()

        # Walls: the head left the board, so the run ends
        if head.xcor() > 290 or head.xcor() < -290 or head.ycor() > 290 or head.ycor() < -290:
            reset_game()

        # Self: the head ran into the body, so the run ends
        for segment in segments:
            if segment.distance(head) < 20:
                reset_game()
                break

        # Eat: the head reached the food
        if head.distance(food) < 20:
            new_food_spot()
            new_segment = turtle.Turtle()
            new_segment.speed(0)
            new_segment.shape("square")
            new_segment.color("lightgreen")
            new_segment.penup()
            segments.append(new_segment)
            score = score + 10
            if delay > 0.05:
                delay = delay - 0.005
            show_score()

    time.sleep(delay)

Key points

  • The window background takes the colour name darkgreen
  • The head takes the colour name lime
  • Each new body segment takes the colour name lightgreen
  • The border is drawn by its own Turtle with the pen down
  • forward(580) walks one side of the square and left(90) turns one corner
  • range(4) repeats the walk and the turn until the square closes
  • The square runs from -290 to 290 on both axes

In this example, the program opens the 600 by 600 window and paints it dark green. A border turtle then lifts its pen and moves to -290, -290. It puts the pen down and walks 580 steps along one side. A left turn of 90 degrees aims it along the next side. The loop repeats the walk and the turn four times and closes the white square. The head takes the colour lime and starts at the centre. The food, the score pen and the game rules stay as they were. The loop still follows, moves, checks the walls, checks the body and checks the food on every tick. The border changes nothing about the rules. It only draws the line at 290 that the wall check has used all along.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

Why does the border leave a white line while the snake and the food leave no line at all?