2

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!)

Skully
  • 2,882
  • 3
  • 20
  • 31
msush
  • 51
  • 4
  • Does this answer your question? https://stackoverflow.com/questions/16119991/how-to-speed-up-pythons-turtle-function-and-stop-it-freezing-at-the-end – BartoszKP Jan 09 '22 at 21:24
  • No, I think the answers to that question are saying to disable the screen refreshing to just show the end result but in my game, the user needs to be able to see the snake moving. – msush Jan 10 '22 at 02:53
  • But you can still refresh the screen manually after you finish drawing the segments. AFAIU now the screen will refresh every single segment you draw, which is a significant slow-down. – BartoszKP Jan 10 '22 at 06:10

1 Answers1

0

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

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 10 '22 at 03:09