1

I'm making a simple snake game in python. I am in the earlier stages of just making the snake move at this point. So I have 3 files, main.py, Turtle_Skin.py and Turtle_Control.py The first part (In Turtle_Skin.py) is working just fine where I need to make the snake take the starting position, however even if I try migrating the code from Turtle_Control.py to main.py (to make sure it executes and doesn't get left behind while importing), it won't execute

My Code with file names:

main.py:

from Turtle_Control import *
from Turtle_Skin import *
positions_goto()

Turtle_Skin.py:

from turtle import *

screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("black")
screen.title("Snake_Food_Game")
screen.tracer(1)
Baby_Turtle = Turtle()
Mommy_Turtle = Turtle()
Daddy_Turtle = Turtle()

All_Turtles = [Baby_Turtle, Mommy_Turtle, Daddy_Turtle]

for turtle in All_Turtles:
    turtle.shape("square")
    turtle.pencolor("white")
    turtle.color("white")


def positions_goto():
    Daddy_Turtle.penup()
    Daddy_Turtle.goto(x=-40, y=0)
    Mommy_Turtle.penup()
    Mommy_Turtle.goto(x=-20, y=0)
    Baby_Turtle.penup()


positions_goto()

screen.exitonclick()

Turtle_Control.py

from Turtle_Skin import *
import time
positions_goto()

is_on = True
while is_on:
    screen.update()
    time.sleep(0.1)

    for part_num in range(len(All_Turtles) - 1, 0, -1):
        xcord = All_Turtles[part_num - 1].xcor()
        ycord = All_Turtles[part_num - 1].ycor()
        All_Turtles[part_num].goto(x=xcord, y=ycord)
    Baby_Turtle.forward(20)
ggorlen
  • 44,755
  • 7
  • 76
  • 106

1 Answers1

0

screen.exitonclick() blocks your code, running the main turtle loop, until you click the screen.

Tracing the code execution:

  1. main.py runs from Turtle_Control import * on line 1
  2. Turtle_Control.py runs from Turtle_Skin import * on line 1
  3. Turtle_Skin.py runs most of the turtle code, then blocks at screen.exitonclick(). After you click, only then does from Turtle_Skin import * on line 1 of Turtle_Control.py resolve so that line 2, import time, can continue. But by then the window's been destroyed so the while loop is much too late.

A good way to figure out what's going on with this behavior is to add print()s to your code to see if the code you care about is even executing, and if so, when. Creating a minimal example of the problem would make the issue obvious:

import turtle

turtle.exitonclick() # => blocks until the screen is clicked
print("hi") # => only executes after the screen was clicked

The original code organization doesn't make much sense. Modules have no obvious responsibility. positions_goto() is called in many different locations. The main code that initializes turtles and runs the game loop is spread across a few files seemingly haphazardly.

With such a small amount of code, creating modules seems premature here. I'd put all of the code into one file until you have things working ("I am in the earlier stages of just making the snake move at this point") and really need obvious separation of concerns. When you do, I'd create different files for different classes (things/entities in the game), primarily. snake.py with class Snake: would be one example. food.py with class Food: might be another potential file.

There should be no "loose" code in the global scope in each file other than a class or function or two. Main-line code (particularly if non-idempotent) in modules should be in an if __name__ == "__main__": block so that it's not invoked simply because the module was imported (which might happen multiple times in an app, as is the case here).

If you want to separate the whole game from main, that's fine, but keep the set up and main loop intact so they execute as a unit.

ggorlen
  • 44,755
  • 7
  • 76
  • 106