How do I run two turtles in python simultaneously?

不羁的心 提交于 2020-01-04 11:43:08

问题


I'm trying to make two turtles move together instead of one moving subsequently after the other. For example:

a = turtle.Turtle()
b = turtle.Turtle()

a.forward(100)
b.forward(100)

But this only makes them move one after the other. Is there a way to make them move together simultaneously?


回答1:


Is there a way to make them move together simultaneously?

The best we can hope to do is make them appear to move simultaneously. Below are three increasingly complex approaches to this problem. But first, let's establish our baseline code, two turtles heading at each other and stopping when they meet at the origin:

from turtle import Screen, Turtle

screen = Screen()

a = Turtle('square', visible=False)
a.speed('slow')
a.color('red')
a.penup()
a.setx(-300)
a.setheading(0)
a.pendown()
a.showturtle()

b = Turtle('circle', visible=False)
b.speed('slow')
b.color('green')
b.penup()
b.setx(300)
b.setheading(180)
b.pendown()
b.showturtle()

### Subsequent variations start here ###

a.forward(300)
b.forward(300)

### Subsequent variations end here ###

screen.mainloop()

The above doesn't do what we want as one turtle moves and then the other. For our first variation, we simply chop up the motion into smaller units and alternate:

###

for _ in range(300):
    a.forward(1)
    b.forward(1)

###

Our next variation uses timer events to control the motion of the two turtles:

###

def move(turtle):
    turtle.forward(1)

    if turtle.distance(0, 0) > 1 :
        screen.ontimer(lambda t=turtle: move(t), 50)

move(a)
move(b)

###

Our final variation uses threading to independently control the two turtles. Each turtle is a thread and there's a third, main thread that handles all the graphics operations for the turtle threads. This is needed as turtle operates atop tkinter which has issues handling graphics from secondary threads:

###

from threading import Thread, active_count
from queue import Queue

QUEUE_SIZE = 1

def process_queue():
    while not actions.empty():
        action, *arguments = actions.get()
        action(*arguments)

    if active_count() > 1:
        screen.ontimer(process_queue, 100)

actions = Queue(QUEUE_SIZE)  # a thread-safe data structure

def move(turtle):
    while turtle.distance(0, 0) > 1:
        actions.put((turtle.forward, 1))

Thread(target=move, args=[a], daemon=True).start()
Thread(target=move, args=[b], daemon=True).start()

process_queue()

###



回答2:


You can't do this as a guaranteed part of the Turtle interface. You could try doing these in parallel processes, but there's no guarantee of simultaneous movement. Some Python run-time systems handle parallel processes with sequential time-slicing of a single process. You may also find that one move completes while the other process is initializing. If you want to try tighter management, build two processes that hold on a process lock; have the main program release both locks in a critical section ... and you might get something close to the desired functionality.

If you're trying to do something this graphically mature, you might consider a larger graphics package, such as PyGame.



来源:https://stackoverflow.com/questions/53199459/how-do-i-run-two-turtles-in-python-simultaneously

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!