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

Python Snake Speed and Delay

Delay is the wait between game beats. A smaller delay makes the game run faster.

The delay variable

delay holds the wait between game beats. It starts at 0.1 seconds.

delay = 0.1

Sleeping for the delay

The loop passes delay to time.sleep() at the end of each tick. A smaller delay means a shorter wait.

    time.sleep(delay)

Faster with every bite

Each bite takes 0.005 off the delay. The if guard stops the delay at the floor.

        if delay > 0.05:
            delay = delay - 0.005

Back to the start speed

reset_game() puts delay back to 0.1. A fresh run starts at the gentle pace again.

    score = 0
    delay = 0.1
    show_score()

Example

import turtle
import time
import random

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

# The snake head
head = turtle.Turtle()
head.speed(0)
head.shape("square")
head.color("white")
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

# 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 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")

# The game loop: redraw, follow, move, check the rules, eat, wait
while True:
    screen.update()

    # 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("grey")
        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

  • delay is the wait between game beats.
  • The loop passes delay to time.sleep() on every tick.
  • delay starts at 0.1.
  • Each bite takes 0.005 off the delay.
  • The if guard keeps delay from dropping to 0.05 or below.
  • The floor gives the game a top speed.
  • reset_game() puts delay back to 0.1.

In this example, delay starts at 0.1 and the loop sleeps for delay on every tick. A bite adds 10 to the score and then lowers delay by 0.005. The if guard only lowers delay while it stays above 0.05. A reset puts delay back to 0.1 for the fresh run.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

What does the if delay > 0.05 guard do?