Search code examples
pythondrawingturtle-graphicspython-turtle

How to make a turtle draw above another one?


I'm making a project where I have a turtle drawing a black line, but following it is another turtle drawing a white line. I want this white line to draw over the black line to "erase" the black line, but the black line remains above the white line.

I am programming this on trinket.io

Here's my code:

import turtle 

#create elements
pen = turtle.Turtle()
follow = turtle.Turtle()
screen = turtle.Screen()


#create variables
positions = [0,-180,0,-180,0,-180,0,-180,0,-180,0,-180,0,-180,0,-180,0,-180,0,-180]


#moving functions
def move_left():
  if pen.xcor() > -180:
    pen.goto(pen.xcor()-10,pen.ycor())
def move_right():
  if pen.xcor() < 180:
    pen.goto(pen.xcor()+10,pen.ycor())
def move_up():
  if pen.ycor() < 180:
    pen.goto(pen.xcor(),pen.ycor()+10)
def move_down():
  if pen.ycor() > -180:
    pen.goto(pen.xcor(),pen.ycor()-10)


#pen setup
pen.speed(1000)
pen.penup()
pen.goto(0,-180)
pen.left(90)
pen.pendown()

follow.left(90)
follow.color("#FFFFF1")
follow.width(50)


#adjust frame refresh settings
pen.tracer(0,0)
rate = 0
refresh = 0


#game functionality
def game():
  screen.onkey(move_left, 'left')
  screen.onkey(move_right, 'right')
  screen.onkey(move_up, 'up')
  screen.onkey(move_down, 'down')
  follow.goto(positions[0],positions[1])
  positions.append(pen.xcor())
  positions.append(pen.ycor())
  positions.pop(0)
  positions.pop(0)


#wait for keys
screen.listen()


#loop
while True:
  game()
  if refresh < rate:
    refresh = refresh + 1
  else:
    pen.update()
    #print(positions)
    refresh = 0

How can I fix my program?


Solution

  • You only need to invoke each screen.onkey() instance once, they gain nothing by being called (indirectly) in a loop. Also, it's not clear why positions is preinitialized with ten positions.

    I'm going to guess that you want a turtle that leaves a trail but that trail has a limited length and the end of it disappears as new trail is laid down. And from your description, you want this to work in trinket.io turtle which means we can't use features like stamps to make this cleaner.

    Below is my rework of your code, that I've tested on trinket.io, which leaves behind it 20 line segments. The oldest line segment disappears as a new one is laid down:

    from turtle import Screen, Turtle
    
    NUMBER_SEGMENTS = 20
    
    # moving functions
    def truncate():
        if len(positions) >= NUMBER_SEGMENTS:
            follower.setposition(positions.pop(0))
    
        screen.update()
    
    def move_left():
        pen.setheading(180)
    
        if pen.xcor() > -180:
            pen.forward(10)
            positions.append(pen.position())
    
        truncate()
    
    def move_right():
        pen.setheading(0)
    
        if pen.xcor() < 180:
            pen.forward(10)
            positions.append(pen.position())
    
        truncate()
    
    def move_up():
        pen.setheading(90)
    
        if pen.ycor() < 180:
            pen.forward(10)
            positions.append(pen.position())
    
        truncate()
    
    def move_down():
        pen.setheading(270)
    
        if pen.ycor() > -180:
            pen.forward(10)
            positions.append(pen.position())
    
        truncate()
    
    # create elements
    screen = Screen()
    
    # adjust frame refresh settings
    screen.tracer(0)
    
    refresh = 0
    
    # pen setup
    pen = Turtle()
    pen.speed('fastest')
    pen.penup()
    pen.sety(-180)
    pen.setheading(90)
    pen.pendown()
    
    follower = pen.clone()
    follower.hideturtle()
    follower.width(3)
    follower.color('#F9F9F9')
    
    # create variables
    positions = []
    
    # wait for keys
    screen.onkey(move_left, 'Left')
    screen.onkey(move_right, 'Right')
    screen.onkey(move_up, 'Up')
    screen.onkey(move_down, 'Down')
    screen.listen()
    screen.update()
    screen.mainloop()
    

    Not perfect, but trinket.io ties our claws a bit. Is this roughly what you're trying to do?