0

For a class (snake class) created from the turtle module in Python:

Problem 1. when the move() method is called, the snake segments are moving backwards instead of forward . The problem seems to be the return function called in each method (I think it is), where the original position of the snake is called, thus it cannot move forward

Fixed this by removing the return function in the positions() method, but a new problem arises when the screen briefly opens and closes, the fault may lie in the move() method [i.e., in this line, snake_segments = self.segments()]

Given are the code for Problem 1, the fix for for problem 2, and the main.py code

Problem 1 (snake segments moving backward instead of forward):

from turtle import Turtle

class Snake:

    def __init__(self):
        self.x = 0
        self.y = 0

    def positions(self):
        start_pos = []

        for _ in range(0, 3):
            start_pos.append((self.x, self.y))
            self.x -= 20
     
        return start_pos


    def segments(self):
        new_positions = self.positions()

        snake_segments = []

        for cord in new_positions:
            new_turtle = Turtle()
            new_turtle.penup()
            new_turtle.shape("square")
            new_turtle.color("white")
            self.x = cord[0]
            self.y = cord[1]
            new_turtle.goto(x=self.x, y=self.y)
            snake_segments.append(new_turtle)

        return snake_segments

    def move(self):
        snake_segments = self.segments()       

        for segment_index in range(len(snake_segments) - 1, 0, -1):

            new_x = snake_segments[segment_index - 1].xcor()
            new_y = snake_segments[segment_index - 1].ycor()
            snake_segments[segment_index].goto(new_x, new_y)

        snake_segments[0].forward(20)

Below is the Fix for Problem 1 but gives Problem 2 (screen opens and closes)

from turtle import Turtle


class Snake:

    def __init__(self):
        self.x = 0
        self.y = 0

    def positions(self):
        start_pos = []

        for _ in range(0, 3):
            start_pos.append((self.x, self.y))
            self.x += 20

        self.segments(start_pos)

    def segments(self, start_pos):
        # new_positions = self.start_pos

        snake_segments = []

        for cord in start_pos:
            new_turtle = Turtle()
            new_turtle.penup()
            new_turtle.shape("square")
            new_turtle.color("white")
            self.x = cord[0]
            self.y = cord[1]
            new_turtle.goto(x=self.x, y=self.y)
            snake_segments.append(new_turtle)

        return snake_segments

    def move(self):
        snake_segments = self.segments()
        #print(snake_segments)

        for segment_index in range(len(snake_segments) - 1, 0, -1):

            new_x = snake_segments[segment_index - 1].xcor()
            new_y = snake_segments[segment_index - 1].ycor()
            snake_segments[segment_index].goto(new_x, new_y)

        snake_segments[0].forward(20)

Below is the main.py file

from turtle import Screen, Turtle import time from snake import Snake
screen = Screen() 
screen.setup(width=600, height=600) 
screen.bgcolor("black") 
screen.title("My Snake Game") 
screen.tracer(0)

snake = Snake()

game_is_on = True

while game_is_on: 
      screen.update()
      time.sleep(0.5)
      snake.move()

screen.exitonclick()
3
  • 2
    The common while loop idiom is not a good way to do a realtime event loop in turtle. Prefer ontimer. Commented Apr 9, 2024 at 0:18
  • The main problem is self.x and self.y being modified in positions(...) and segments(...) while they should only be modified in move(...). Commented Apr 9, 2024 at 1:54
  • @ChrisFu doesn't seem to be the case Commented Apr 9, 2024 at 22:55

3 Answers 3

1

Let's toss ontimer() into the mix, as @ggorlen suggests, and eliminate all the self.x and self.y stuff since it isn't consulted nor updated by your move() method anyway:

from turtle import Screen, Turtle

class Snake:
    def __init__(self):
        self.snake_segments = self.create_positions()

    def create_positions(self):
        x, y = (0, 0)
        positions = []

        for _ in range(3):
            positions.append((x, y))
            x += 20

        return self.create_segments(positions)

    def create_segments(self, starting_positions):
        snake_segments = []

        for position in starting_positions:
            turtle = Turtle()
            turtle.penup()
            turtle.shape("square")
            turtle.color("white")
            turtle.goto(position)

            snake_segments.append(turtle)

        return snake_segments

    def move(self):
        for segment_index in range(len(self.snake_segments) - 1, 0, -1):
            new_position = self.snake_segments[segment_index - 1].position()
            self.snake_segments[segment_index].goto(new_position)

        self.snake_segments[0].forward(20)

def slither():
    snake.move()
    screen.update()
    screen.ontimer(slither, 500)

screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("black")
screen.title("My Snake Game")
screen.tracer(False)

snake = Snake()

screen.update()

slither()

screen.exitonclick()

I didn't experience any "screen briefly opens and closes" when I ran your code. If this is still an issue, specify what environment you're using to run this code.

Sign up to request clarification or add additional context in comments.

Comments

0

I don't use turtle, but reading your post, I have this idea : segments should be a global variable ? Here you loose values. See that : screen.update returning an error (Python Turtle module)

1 Comment

I can use constants for starting positions eg. START_POS = [(X1,Y1), (X2,Y2), (X3,Y3)] and it will work, but I want to use the current positions() method approach. My code works well if I changed to procedural instead of the current OOP code
0

Finally worked it out.

Code 1 Problem Solution. It was not suitable to return a function where the position kept updating. Had to remove the lists created in different methods and initialize it instead.

Code 2 Problem Solution: Had to call the all the methods in the main.py file. (previously didn't do this because the return function approach used in Code 1 would have called the functions).

The code is below

from turtle import Turtle


class Snake:

    def __init__(self):
        self.x = 0
        self.y = 0
        self.start_pos = []       # Solution code 1: move this here
        self.snake_segments = []  # Solution code 1: move this here

    def positions(self):

        for _ in range(0, 3):
            self.start_pos.append((self.x, self.y))
            self.x -= 20
        print(self.start_pos)



    def segments(self):

        for coord in self.start_pos:
            new_turtle = Turtle()
            new_turtle.penup()
            new_turtle.shape("square")
            new_turtle.color("white")
            self.x = coord[0]
            self.y = coord[1]
            new_turtle.goto(x=self.x, y=self.y)
            self.snake_segments.append(new_turtle)



    def move(self):

        for segment_index in range(len(self.snake_segments) - 1, 0, -1):

            new_x = self.snake_segments[segment_index - 1].xcor()
            new_y = self.snake_segments[segment_index - 1].ycor()
            self.snake_segments[segment_index].goto(new_x, new_y)

        self.snake_segments[0].forward(20)


# below is main.py

from turtle import Screen, Turtle
import time
from snake import Snake

screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("black")
screen.title("My Snake Game")
screen.tracer(0)


snake = Snake()

snake.positions()               # Solution code 2: call here
snake.segments()                # Solution code 1: call here


game_is_on = True

while game_is_on:
    screen.update()                   
    time.sleep(1.0)
    snake.move()

screen.exitonclick()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.