我有一个作业,要求将两只乌龟放在赛道上(大小相同但赛道不同)。我可以让它们移动,但只有当第一个移动了一半轨道时,第二个才会移动。我不知道如何让乌龟同时移动。这是我的代码:
import turtle
import random
import time
wn = turtle.Screen()
wn.bgcolor("lightgreen")
t = turtle.Turtle()
t.shape('turtle')
t.color('red')
t2 = turtle.Turtle()
t2.shape('turtle')
t2.color('blue')
#user input function
p = float(input('please insert the perimeter:'))
#set the track
def drawTrack(p,r):
shortside = (p/2.0)/(r+1)
longside = r*shortside
turtle.setup((shortside*2)+60, longside +40)
t.penup()
t2.penup()
t.setposition(-shortside-10, -longside/2)
t2.setposition(10, -longside/2)
for i in range (2):
#first track
t.speed(1)
t.pendown()
t.forward(shortside)
t.left(90)
t.forward(longside)
t.left(90)
#second track
t2.speed(1)
t2.pendown()
t2.forward(shortside)
t2.left(90)
t2.forward(longside)
t2.left(90)
drawTrack(p,2)
wn.exitonclick()
有几种方法可以解决这个问题。
使用
screen.ontimer()
事件的一种方法(请参阅海龟文档)。这种方法很好,因为您可以将海龟调整为实际时钟时间,并且这可以在海龟事件循环内运行,以便其他事件也可以发生(如exitonclick()
)。
我下面使用的方法是将海龟运动分解为 Python generator 中的微小步骤,它在每次运动后都会产生结果。这使我们能够在海龟之间交替。比赛发生在海龟事件循环之前,因此
exitonclick()
在比赛结束之前无效。
为了提供速度差异,我使用海龟绘制速度作为运动计算的一部分,因此如果您说
turtle1.speed("fast")
,它会比turtle2.speed("slow")
移动得更快。还有其他方法可以使用随机和/或变化的速度来解决此问题。
我已将周长提示更改为对话框,并进行了各种样式调整:
from turtle import Turtle, Screen
screen = Screen()
screen.bgcolor("lightgreen")
turtle1 = Turtle(shape='turtle')
turtle1.color('red')
turtle1.speed("slow") # = 3
turtle1.penup()
turtle2 = Turtle(shape='turtle')
turtle2.color('blue')
turtle2.speed(4) # "slow" (3) < 4 < "normal" (6)
turtle2.penup()
# user input function
perimeter = screen.numinput("Track Perimeter", "Please enter the perimeter:", default=2000, minval=500, maxval=3000)
def full_track_crawl(turtle, shortside, longside):
speed = turtle.speed()
turtle.pendown()
for j in range (2):
for i in range(0, int(shortside), speed):
turtle.forward(speed)
yield(0)
turtle.left(90)
for i in range(0, int(longside), speed):
turtle.forward(speed)
yield(0)
turtle.left(90)
turtle.penup()
# set the track
def drawTrack(perimeter, ratio):
shortside = (perimeter / 2.0) / (ratio + 1)
longside = ratio * shortside
screen.setup(shortside * 2 + 60, longside + 40)
turtle1.setposition(-shortside - 10, -longside / 2)
turtle2.setposition(10, -longside / 2)
generator1 = full_track_crawl(turtle1, shortside, longside)
generator2 = full_track_crawl(turtle2, shortside, longside)
while (next(generator1, 1) + next(generator2, 1) < 2):
pass
drawTrack(perimeter, 2)
screen.exitonclick()
快乐赛车!
我让每只海龟重复移动一个微小的增量,这样它们之间的最大距离就只有 1 个像素:
# Setup
import turtle
screen = turtle.Screen()
screen.bgcolor("white")
screen.title("Turtle Movement")
screen.setup(width=500, height=500)
# Object 1 set up
obj1 = turtle.Turtle()
obj1.color("red") # Sets obj1's colour
obj1.speed(0) # The drawing speed will go as fast as it can if it is set to zero
obj1.penup() # Don't want it to draw a line as I goes to 0, -50
obj1.goto(0, -50) # goes to 0, -50
obj1.pendown() # Now we want it to draw
# Object 2 set up
obj2 = turtle.Turtle()
obj2.color("blue") # sets obj2's colour
obj2.speed(0) # The drawing speed will go as fast as it can if it is set to zero
obj2.penup() # Don't want it to draw a line as I goes to 0, -50
obj2.goto(0, 50) # goes to 0, 50
obj2.pendown() # Now we want it to draw
# Movement of objects
while True: # infinite loop
obj1.forward(1) # Moves obj1 forwards by 1
obj2.forward(1) # Moves obj2 forwards by 1
注意: ‘移动量’越小, 例如
forward(Movement amount is in here)
,
运动变得越顺畅,但你会失去速度。
我鼓励您调整值并进行实验!
以循环方式小增量移动海龟(如本线程其他地方所述)对于许多情况来说是一个很好的解决方案,但更灵活和通用的解决方案是使用
tracer
、ontimer
禁用海龟对事件循环的控制和update
:
from random import randint
from turtle import Screen, Turtle
def tick():
for t in turtles:
t.forward(1)
if randint(0, 1):
t.left(randint(-5, 5))
screen.update()
screen.ontimer(tick, 1000 // 30)
screen = Screen()
screen.tracer(0)
turtles = [Turtle() for _ in range(100)]
for t in turtles:
t.setheading(randint(0, 360))
tick()
screen.exitonclick()
另请参阅:Python 多只海龟(看似)同时移动
解决方案是禁用更新每只海龟的位置,然后在计算出新位置后强制更新整个屏幕。
import turtle
# our two turtle instances
first, second = turtle.Turtle(), turtle.Turtle()
first.tracer(False) # disable updating view on screen for this turtle!
second.tracer(False)
# make one move - note this will not appear on screen.
first.forward(50)
second.left(20)
# when you are ready to see the whole screen update
turtle.update()