Reputation: 659
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
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