How can I prevent my snake game from slowing down every time a segment is added?

Viewed 94

I'm coding a simple snake game in Python 3 with the turtle module, every time the snake eats the food though it gets a little slower, and eventually the game is impossible to play.

I want to make the speed constant and fast enough that you can play the game without getting annoyed because the snake is moving super slow but I don't know how.

Here is the code I have so far, I still have a few other things to do but just ignore those.

#------------------------------------------SETUP------------------------------------------
#import statements
import turtle
import random

#variables
score = 0
up = True
down = False 
left = False
right = False
high_score=0

#background
wn = turtle.Screen()
wn.title("Snake Game")
wn.bgcolor("black")
wn.setup(width = 600, height =600) #set height and width of the screen

#create snake head
head = turtle.Turtle()
head.shape("square")
head.color("green")
head.penup()
head.goto(0,0)

#food
food = turtle.Turtle()
food.shape("square")
food.color("red")
food.penup()
food.speed = "fastest"
food.goto(0,100)

#segments
segments = []
segment_locationsy=[]
segment_locationsx=[]

#create pen to write score
pen = turtle.Turtle()
pen.speed(0)
pen.shape("square")
pen.color("green")
pen.penup()
pen.hideturtle()
pen.goto(0,260)
pen.pendown()

pen.write(pen.write("PRESS SPACE TO START" , align = "center", font=("Courier", 24, "normal")))
#------------------------------------------FUNCTIONS------------------------------------------
# define a function for each direction
#TODO: FIX REPETITIVENESS
def go_up():
    global up,down,left,right
    if (down != True):
        up = True
        down = False
        left = False
        right = False
def go_down():
    global up,down,left,right
    if (up != True):
        up = False
        down = True
        left = False
        right = False
def go_right():
    global up,down,left,right
    if (left != True):
        up = False
        down = False
        left = False
        right = True
def go_left():
    global up,down,left,right
    if (right != True):
        up = False
        down = False
        left = True
        right = False

#create a function to make the turtle move
def move():
    if up:
        head.sety(head.ycor()+5)
    if down:
        head.sety(head.ycor()-5)  
    if left: 
        head.setx(head.xcor()-5)
    if right:
        head.setx(head.xcor()+5)

#function to reset the food location
def reset_food():
    new_x = random.randint(-280,280)
    new_y = random.randint(-280,280)
    if (head.distance(new_x,new_y)<20): #make sure that apple doesn't overlap with the snake
        reset_food()
    for i in segments:
        if ((head.distance(i)<20)):
            reset_food()
    food.hideturtle()
    food.goto(new_x,new_y)
    food.showturtle()
#function to add to the score
def add_score():
    global score
    global high_score
    score = score + 1
    if (score >high_score):
        high_score = high_score + 1
    pen.clear()
    pen.write("Score:" + str(score) + " High score:" + str(high_score) , align = "center", font=("Courier", 24, "normal"))
    

def start_game():
    global up, down, left, right
    global score
    pen.goto(0,260)
    food.goto(0,100)
    score = 0
    up = True
    down = False 
    left = False
    right = False
    pen.clear()
    game_go = True
    segments = []
    segment_locationsy=[]
    segment_locationsx=[]
    head.goto(0,0)
    # call function every time screen is updated
    var = 0
    while game_go:
        wn.update()
        move()
        #assign a key for each function
        wn.listen()
        wn.onkeypress(go_up, "i")
        wn.onkeypress(go_down, "k")
        wn.onkeypress(go_left, "j")
        wn.onkeypress(go_right, "l")
        #reset snakehead when it touches the border, stop movement and reset direction, clear segments
        if (head.xcor() > 290) or (head.xcor() < -290) or (head.ycor() > 290) or (head.ycor() < -290):
            game_go = False
        # add a segment every time it touches food
        if (head.distance(food)<=15):
            segment = turtle.Turtle("square")
            segment.color("green")
            segment.hideturtle()
            segment.penup()
            segment.goto(head.xcor(),head.ycor())
            segment.showturtle()
            segment.speed("fastest")
            segments.append(segment)
            reset_food()
            add_score()
        #segments follow along
        segment_locationsy.append(head.ycor())
        segment_locationsx.append(head.xcor())
        var2 = 1
        for i in segments:
            i.setx(segment_locationsx[var-5*var2])
            i.sety(segment_locationsy[var-5*var2])
            if (head.distance(i) < 15): #snake dies if it touches itself
                game_go=False
            var2+=1
        var+=1


        #write game over
    pen.clear()
    pen.pu()
    pen.sety(pen.ycor()-50)
    pen.write("GAME OVER" , align = "center", font=("Courier", 24, "normal"))
    pen.pu()
    pen.sety(pen.ycor()-50)
    pen.write("press space to restart" , align = "center", font=("Courier", 24, "normal"))

    for i in segments:
        i.clear
        i.hideturtle()
    

#------------------------------------------RUN GAME------------------------------------------
while True:
    wn.listen()
    wn.onkeypress(start_game,"space")
    wn.update()

I've tried looking this up but just got more confused and couldn't implement anything into my code (if anyone answers this please include a beginner-friendly explanation as to how to fix the problem, thank you!)

1 Answers

Well, more segments mean more time to procces movement, I would try instead of moving all segmets, move last segment to front.

Related