我是线程新手,所以如果我遗漏了一些完全明显的东西,请原谅。
这是我的代码(海龟竞赛):
(跳到线程部分代码的底部)
import turtle
from random import randint
import threading
n = turtle.Turtle()
n.speed(10)
n.hideturtle()
n.penup()
n.goto(-600, 300)
n.pendown()
for x in range(1, 51):
n.forward(12)
n.write(x)
n.forward(12)
n.right(90)
n.forward(270)
n.right(90)
n.forward(1200)
n.right(90)
n.forward(270)
n.right(180)
n.forward(15)
n.left(90)
for x in range(0, 4):
n.forward(1200)
n.right(90)
n.forward(30)
n.right(90)
n.forward(1200)
n.left(90)
n.forward(30)
n.left(90)
n.forward(1200)
n.right(90)
red = turtle.Turtle()
blue = turtle.Turtle()
green = turtle.Turtle()
orange = turtle.Turtle()
brown = turtle.Turtle()
black = turtle.Turtle()
pink = turtle.Turtle()
purple = turtle.Turtle()
turtles = {
red: ['red', 270],
blue: ['blue', 240],
green: ['green', 210],
orange: ['orange', 180],
brown: ['brown', 150],
black: ['black', 120],
pink: ['pink', 90],
purple: ['purple', 60]
}
for x in turtles:
x.color(turtles[x][0])
x.shape('turtle')
x.penup()
x.goto(-600, turtles[x][1])
def move_red(num1, num2):
for y in range(0, 240):
red.speed(randint(num1, num2))
red.forward(5)
return
def move_blue(num1, num2):
for y in range(0, 240):
blue.speed(randint(num1, num2))
blue.forward(5)
return
def move_green(num1, num2):
for y in range(0, 240):
green.speed(randint(num1, num2))
green.forward(5)
return
def move_orange(num1, num2):
for y in range(0, 240):
orange.speed(randint(num1, num2))
orange.forward(5)
return
def move_brown(num1, num2):
for y in range(0, 240):
brown.speed(randint(num1, num2))
brown.forward(5)
return
def move_black(num1, num2):
for y in range(0, 240):
black.speed(randint(num1, num2))
black.forward(5)
return
def move_pink(num1, num2):
for y in range(0, 240):
pink.speed(randint(num1, num2))
pink.forward(5)
return
def move_purple(num1, num2):
for y in range(0, 240):
purple.speed(randint(num1, num2))
purple.forward(5)
return
t1 = threading.Thread(target = move_red, args = [1, 10])
t2 = threading.Thread(target = move_blue, args = [1, 10])
t3 = threading.Thread(target = move_green, args = [1, 10])
t4 = threading.Thread(target = move_orange, args = [1, 10])
t5 = threading.Thread(target = move_brown, args = [1, 10])
t6 = threading.Thread(target = move_black, args = [1, 10])
t7 = threading.Thread(target = move_pink, args = [1, 10])
t8 = threading.Thread(target = move_purple, args = [1, 10])
ts = [t1, t2, t3, t4, t5, t6, t7, t8]
for x in ts:
x.start()
turtle.done()
如果你在编辑器中运行它,你会看到乌龟随机停留。当我运行2个线程时,这不会发生。 .join()
也无济于事。请向我解释为什么线程不起作用。
答案 0 :(得分:0)
这可以完成,但您需要限制调用tkinter到主线程的乌龟操作。下面是我的拆解和重建您的程序以这种方式工作并删除冗余。 (我离开了你可以添加回来的背景图。)我使用线程安全队列数据结构来在线程和tkinter之间进行通信:
from threading import Thread, active_count
from turtle import Turtle, Screen
from random import randint
from queue import Queue # use for thread-safe communications
QUEUE_SIZE = 1 # set higher the more unused hardware threads you have
COLORS = ['red', 'blue', 'green', 'orange', 'brown', 'black', 'pink', 'purple']
def move_turtle(turtle):
for _ in range(240):
actions.put((turtle.forward, randint(1, 10)))
def process_queue():
while not actions.empty():
action, argument = actions.get()
action(argument)
if active_count() > 1:
screen.ontimer(process_queue, 100)
actions = Queue(QUEUE_SIZE)
screen = Screen()
screen.setup(1200, 600)
threads = []
for y, color in enumerate(COLORS):
turtle = Turtle('turtle', visible=False)
turtle.color(color)
turtle.speed('fastest')
turtle.penup()
turtle.goto(-600, 270 - y * 30)
turtle.showturtle()
thread = Thread(target=move_turtle, args=[turtle])
threads.append(thread)
for thread in threads:
thread.start()
process_queue()
screen.mainloop()
我不希望海龟向前移动;我想要它们 以不同的速度向前移动相同的距离
您可以使用我设置的环境执行此操作:
def move_turtle(turtle):
for _ in range(240):
actions.put((turtle.speed, randint(1, 10)))
actions.put((turtle.forward, 5))
但是turtle.speed()
是关于绘制速度而你只是(不)绘制一条五像素线,因此绘制速度差别不大。在比赛的中间,这就是正在发生的事情:
即使在比赛开始之前将海龟设置为随机速度,而不是改变它们,也没有区别。我认为改变前进距离会带来更激动人心的比赛。
答案 1 :(得分:0)
我创建了一个名为height
的库,它使用与@cdlane在答案中提供的方法相同的方法,但在幕后进行“智能”工作。
你在gitlab上找到了这个库:https://gitlab.com/zvone/threaded_turtle
以下是与问题中相同的代码,经过修改后可与mat-row
库配合使用:
threaded_turtle
但是,代码可以变得更简单。我会做这样的事情:
threaded_turtle
另请注意,我使用的是import turtle
from random import randint
from threaded_turtle import ThreadSerializer, TurtleThread
n = turtle.Turtle()
n.speed(10)
n.hideturtle()
n.penup()
n.goto(-600, 300)
n.pendown()
for x in range(1, 51):
n.forward(12)
n.write(x)
n.forward(12)
n.right(90)
n.forward(270)
n.right(90)
n.forward(1200)
n.right(90)
n.forward(270)
n.right(180)
n.forward(15)
n.left(90)
for x in range(0, 4):
n.forward(1200)
n.right(90)
n.forward(30)
n.right(90)
n.forward(1200)
n.left(90)
n.forward(30)
n.left(90)
n.forward(1200)
n.right(90)
red = turtle.Turtle()
blue = turtle.Turtle()
green = turtle.Turtle()
orange = turtle.Turtle()
brown = turtle.Turtle()
black = turtle.Turtle()
pink = turtle.Turtle()
purple = turtle.Turtle()
turtles = {
red: ['red', 270],
blue: ['blue', 240],
green: ['green', 210],
orange: ['orange', 180],
brown: ['brown', 150],
black: ['black', 120],
pink: ['pink', 90],
purple: ['purple', 60]
}
for x in turtles:
x.color(turtles[x][0])
x.shape('turtle')
x.penup()
x.goto(-600, turtles[x][1])
def move_red(red, num1, num2):
for y in range(0, 240):
red.speed(randint(num1, num2))
red.forward(5)
return
def move_blue(blue, num1, num2):
for y in range(0, 240):
blue.speed(randint(num1, num2))
blue.forward(5)
return
def move_green(green, num1, num2):
for y in range(0, 240):
green.speed(randint(num1, num2))
green.forward(5)
return
def move_orange(orange, num1, num2):
for y in range(0, 240):
orange.speed(randint(num1, num2))
orange.forward(5)
return
def move_brown(brown, num1, num2):
for y in range(0, 240):
brown.speed(randint(num1, num2))
brown.forward(5)
return
def move_black(black, num1, num2):
for y in range(0, 240):
black.speed(randint(num1, num2))
black.forward(5)
return
def move_pink(pink, num1, num2):
for y in range(0, 240):
pink.speed(randint(num1, num2))
pink.forward(5)
return
def move_purple(purple, num1, num2):
for y in range(0, 240):
purple.speed(randint(num1, num2))
purple.forward(5)
return
ctrl = ThreadSerializer()
t1 = TurtleThread(ctrl, red, target=move_red, args=[1, 10])
t2 = TurtleThread(ctrl, blue, target=move_blue, args=[1, 10])
t3 = TurtleThread(ctrl, green, target=move_green, args=[1, 10])
t4 = TurtleThread(ctrl, orange, target=move_orange, args=[1, 10])
t5 = TurtleThread(ctrl, brown, target=move_brown, args=[1, 10])
t6 = TurtleThread(ctrl, black, target=move_black, args=[1, 10])
t7 = TurtleThread(ctrl, pink, target=move_pink, args=[1, 10])
t8 = TurtleThread(ctrl, purple, target=move_purple, args=[1, 10])
ts = [t1, t2, t3, t4, t5, t6, t7, t8]
for x in ts:
x.start()
ctrl.run_forever()
,而不是import turtle
import time
from random import randint
from threaded_turtle import ThreadSerializer, TurtleThread
def draw_background():
n = turtle.Turtle()
n.speed(10)
n.hideturtle()
n.penup()
n.goto(-600, 300)
n.pendown()
for x in range(1, 51):
n.forward(12)
n.write(x)
n.forward(12)
n.right(90)
n.forward(270)
n.right(90)
n.forward(1200)
n.right(90)
n.forward(270)
n.right(180)
n.forward(15)
n.left(90)
for x in range(0, 4):
n.forward(1200)
n.right(90)
n.forward(30)
n.right(90)
n.forward(1200)
n.left(90)
n.forward(30)
n.left(90)
n.forward(1200)
n.right(90)
def move_turtle(t, num1, num2):
for y in range(0, 240):
time.sleep(randint(num1, num2) * 0.02)
t.forward(randint(1, 10))
return
draw_background()
ctrl = ThreadSerializer()
colors = 'red', 'blue', 'green', 'orange', 'brown', 'black', 'pink', 'purple'
threads = []
for i, color in enumerate(colors):
t = turtle.Turtle()
t.color(color)
t.shape('turtle')
t.penup()
t.goto(-600, 270 - 30 * i)
threads.append(TurtleThread(ctrl, t, target=move_turtle, args=[1, 10]))
for thread in threads:
thread.start()
ctrl.run_forever()
,因为如果您不想更改它移动的距离,这是减慢乌龟速度的正确方法。
结果: