Denny Crane
Denny Crane

Reputation: 659

Turtle - screen.update() not working with copy method?

I have a list with several turtle instances. I want to create a copy of one object and let this one move forward.

This works fine. But when I disable screen udpates and do it manually in my code it gives me a different result and I don't see the turtle on its new position. But I do see that it has moved there.

Here is an example. This produces the expected output. But as soon as I disable tracer and do a manual update it behaves weirdly.

from turtle import Screen, Turtle
from copy import copy


screen = Screen()
screen.setup(width=250, height=250)
#screen.tracer(0)

turtles = [Turtle(), Turtle()]

for i in range(10):
    #screen.update()

    new_turtle = copy(turtles[0])

    new_turtle.forward(10)
    turtles.append(new_turtle)

screen.exitonclick()

Upvotes: 0

Views: 34

Answers (1)

furas
furas

Reputation: 142985

First: I had to use [-1] instead of [0] to see turtles in one line.


On my Linux it never works correctly with copy(). With trace(0) and without trace(0) it shows two turtles on screen (or both in the same place so I see only one). And screen.turtles() also shows only two turtles.

for turtle in screen.turtles():
    print(f'turtle: {turtle} : {turtle.pos()}')
turtle: <turtle.Turtle object at 0x72963525dfd0> : (0.00,0.00)
turtle: <turtle.Turtle object at 0x729635013d90> : (0.00,0.00)

I had to assign new _TurtleImage to turtle and append it to screen to see it on screen.
I found this in source code of .clone()

for i in range(10):

    new_turtle = copy(turtles[-1])
    new_turtle.turtle = _TurtleImage(screen, turtles[-1].turtle.shapeIndex)
    screen._turtles.append(new_turtle)

    new_turtle.forward(10)
    
    turtles.append(new_turtle)

    screen.update()

But in source code of .clone() you can see it makes other things.
And code always works for me when I use .clone() instead of copy().
And code is cleaner and shorter with .clone().

for i in range(10):

    new_turtle = turtles[-1].clone()    # works

    new_turtle.forward(10)
    
    turtles.append(new_turtle)

    screen.update()

I don't know why original code works for you without trace(0)
but I think standard method (without trace(0)) may do something more than only run update()
but I didn't find it in source code.


My full code which I used for test - with few other ideas in comments

from turtle import Screen, Turtle, _TurtleImage
from copy import copy, deepcopy


screen = Screen()
#screen.setup(width=250, height=250)
screen.tracer(0)

turtles = [Turtle(), Turtle()]

for i in range(10):

    #new_turtle = copy(turtles[-1])       # all turtles use the same position
    #new_turtle.screen = turtles[-1].screen
    #new_turtle.turtle = _TurtleImage(screen, turtles[-1].turtle.shapeIndex)
    #screen._turtles.append(new_turtle)

    #new_turtle = deepcopy(turtles[-1])  # raise error
    new_turtle = turtles[-1].clone()    # works

    new_turtle.forward(10)
    #new_turtle._update_data()
    #new_turtle._drawturtle()
    
    turtles.append(new_turtle)

    screen.update()

for index, t in enumerate(turtles, 1):
    print(f'{index:2}: {t.getscreen()} : {t.pos()}')
    
for turtle in screen.turtles():
    print(f'turtle: {turtle} : {turtle.pos()}')
        
screen.exitonclick()

Upvotes: 1

Related Questions