2

My goal is to be able to make a snake(three turtles next to each other) move at the same time and also make the snake turn using arrow keys. I have tried the ontimer method/function but it does not work as expected. Here is my code:

import make_snake
from turtle import Turtle, Screen

game_is_on = True

screen = Screen()
screen.setup(600, 600)
screen.bgcolor("black")
screen.title("Snake Game")

snake_seg1 = make_snake.snake_segments[0]
snake_seg2 = make_snake.snake_segments[1]
snake_seg2.setheading(snake_seg1.heading())
snake_seg3 = make_snake.snake_segments[2]
snake_seg3.setheading(snake_seg2.heading())

def move_forward():
    snake_seg1.forward(20)

def move_backward():
    snake_seg1.backward(20)

def turn_left():
    snake_seg1.left(90)

def turn_right():
    snake_seg1.right(90)

screen.onkey(move_forward, "Up")
screen.onkey(move_backward, "Down")
screen.onkey(turn_left, "Left")
screen.onkey(turn_right, "Right")

while game_is_on:
    for seg in make_snake.snake_segments:
        seg.forward(20)

    # def follow_head():    
        # snake_seg1.forward(20)
        # snake_seg2.setheading(snake_seg1.heading())
        # snake_seg2.forward(20)
        # snake_seg3.setheading(snake_seg2.heading())
        # snake_seg3.forward(20)
        # screen.ontimer(follow_head, 0)

screen.exitonclick()

File make_snake:

from turtle import Turtle

start_positions = [0, 20, 40]
snake_segments = []

for position in start_positions:
    snake_part = Turtle(shape="square")
    snake_part.color("white")
    snake_part.penup()
    snake_part.backward(position)
    snake_segments.append(snake_part)

What can I fix in my code to make it stop moving one turtle at a time?

2 Answers2

0

Your program has at least one problem: you use onkey() but forgot to call listen() to allow key events.

Here's a minimalist rework of your code to get basic snake movement working, it just supports right and left turns:

from turtle import Turtle, Screen

SEGMENT_SIZE = 20

START_COORDINATES = [-SEGMENT_SIZE * count for count in range(5)]

def turn_left():
    snake_segments[0].left(90)
    screen.update()

def turn_right():
    snake_segments[0].right(90)
    screen.update()

def move_forward():
    for index in range(len(snake_segments) - 1, 0, -1):
        snake_segments[index].goto(snake_segments[index - 1].position())

    snake_segments[0].forward(SEGMENT_SIZE)
    screen.update()
    screen.ontimer(move_forward, 250)

screen = Screen()
screen.setup(600, 600)
screen.title("Snake Game")
screen.tracer(False)

snake_segments = []

for position in START_COORDINATES:
    snake_segment = Turtle(shape='circle', visible=False)
    snake_segment.penup()
    snake_segment.setx(position)
    snake_segment.showturtle()

    snake_segments.append(snake_segment)

snake_segments[0].color('red')

screen.onkey(turn_left, 'Left')
screen.onkey(turn_right, 'Right')
screen.listen()
screen.update()

move_forward()

screen.exitonclick()

Be careful, it's easy to lose the snake off the edge of the window and not be able to get it back again!

cdlane
  • 40,441
  • 5
  • 32
  • 81
-1

The thing you might be looking for here is called multiprocessing. There is an eponymous library to execute lines of code simultaneously in Python. For reference look at the following thread: Python: Executing multiple functions simultaneously

Dominic K.
  • 19
  • 5