告诉 Python 只乌龟以随机速度沿着特定路径前进

Tell a Python turtle to go in a certain path at a random speed

我有一个 track 需要海龟四处移动,但我不知道如何告诉它们以随机速度沿着特定路径移动。我知道这是一个要求很高的问题,但请告诉我我需要做什么才能开始创建路径。到目前为止我的代码是:

#==========================================================

#                       GAME

#==========================================================
from PIL import Image, ImageTk
from turtle import *
import turtle
from random import randint

# GUI options
screen = turtle.Screen()
screen.setup(1225, 1000)

pil_img = Image.open("eightLane.jpg")  # Use PIL to open .jpg image.
tk_img = ImageTk.PhotoImage(pil_img)  # Convert it into something tkinter can use.

canvas = turtle.getcanvas()  # Get the tkinter Canvas of this TurtleScreen.
# Create a Canvas image object holding the tkinter image.
img_obj_id = canvas.create_image(0, 0, image=tk_img, anchor='center')

title("RACING TURTLES")

#==========================

#   Creating the turtles

#==========================

#NOTES

# turtle moves down by 30 each time
# turtle notes are
#   turtle 1    red
#   turtle 2    yellow
#   turtle 3    blue
#   turtle 4    green
#   turtle 5    dark goldenrod
#   turtle 6    blue violet
#   turtle 7    magenta
#   turtle 8    light slate gray

speed(-10) #speed of the turtles lower is faster 

#turtle one 
one=Turtle() #name of the turtle
one.color('red') #color of the turtle 
one.shape('turtle') #shape of the turtle 
one.penup() #makes the trail line
one.goto(20,90) #starting space #first number is horizontal position second is vertical
one.pendown()
for turn in range(54): # how many times it rotates
    one.right(10) # how far the turtle spins each rotation 

#turtle two 
two=Turtle()
two.color('yellow')
two.shape('turtle')
two.penup()
two.goto(-40,125)
two.pendown()
for turn in range(54): 
    two.left(10) 

#turtle three
three=Turtle()
three.color('blue')
three.shape('turtle')
three.penup()
three.goto(-110,150)
three.pendown()
for turn in range(54): 
    three.right(10)

#turtle four
four=Turtle()
four.color('green')
four.shape('turtle')
four.penup()
four.goto(-180,170)
four.pendown()
for turn in range(55): 
    four.left(10)

#turtle five
five=Turtle()
five.color('dark goldenrod')
five.shape('turtle')
five.penup()
five.goto(-250,185)
five.pendown()
for turn in range(52): 
    five.right(10)

#turtle six
six=Turtle()
six.color('blue violet')
six.shape('turtle')
six.penup()
six.goto(-350,180)
six.pendown()
for turn in range(57): 
    six.left(10)

#turtle seven
seven=Turtle()
seven.color('magenta')
seven.shape('turtle')
seven.penup()
seven.goto(-460,150)
seven.pendown()
for turn in range(50): 
    seven.right(10)

#turtle eight
eight=Turtle()
eight.color('light slate gray')
eight.shape('turtle')
eight.penup()
eight.goto(-550,110)
eight.pendown() 
for turn in range(60): 
    eight.left(10)

#announces the winner
a= ('TODAYS WINNER IS:')
goto(0,-100) # where the winner is displayed
write(a, font=("Arial", 14, "bold"))
addk=0
addkk=0
addkkk=0
addkkkk=0
addkkkkk=0
addkkkkkk=0
addkkkkkkk=0
addkkkkkkkk=0


#================================================

#               Race Code

#================================================
for turn in range(180):
    turtleone=randint(1,5) 
    turtletwo=randint(1,5)
    turtlethree=randint(1,5)
    turtlefour=randint(1,5)
    turtlefive=randint(1,5)
    turtlesix=randint(1,5)
    turtleseven=randint(1,5)
    turtleeight=randint(1,5) 

    one.forward(turtleone) 
    two.forward(turtletwo)
    three.forward(turtlethree) 
    four.forward(turtlefour)
    five.forward(turtlefive)
    six.forward(turtlesix)
    seven.forward(turtleseven)
    eight.forward(turtleeight) 


# winning menu p2

    addk+=turtleone
    addkk+=turtletwo
    addkkk+=turtlethree
    addkkkk+=turtlefour
    addkkkkk+=turtlefive
    addkkkkkk+=turtlesix
    addkkkkkkk+=turtleseven
    addkkkkkkkk+=turtleeight

    if addk>=500:
        one.penup()
        one.goto(10,-120)
        break
    elif addkk>=500:
        two.penup()
        two.goto(10,-120)
        break
    elif addkkk>=500:
        three.penup()
        three.goto(10,-120)
        break
    elif addkkkk>=500:
        four.penup()
        four.goto(10,-120)
        break 
    elif addkkkkk>=500:
        five.penup()
        five.goto(10,-120)
        break
    elif addkkkkkk>=500:
        six.penup()
        six.goto(10,-120)
        break
    elif addkkkkkkk>=500:
        seven.penup()
        seven.goto(10,-120)
        break
    elif addkkkkkkkk>=500:
        eight.penup()
        eight.goto(10,-120)
        break

抱歉代码堆积如山,我不确定具体路径在哪里,所以我只是把整个东西都放进去。任何建议或帮助将不胜感激。

您需要了解围绕圆和椭圆周长的运动。以及 polarcartesian 坐标。下面是一个粗略的示例,如果没有错误的话,它包含了基本思想,但它需要工作。

但首先,让我们解决一些具体的代码问题:

speed(-10)

这根本就是废话。错误的乌龟,无效的论点。重新阅读文档。与其付出所有这些努力:

pil_img = Image.open("eightLane.jpg")  # Use PIL to open .jpg image.
tk_img = ImageTk.PhotoImage(pil_img)  # Convert it into something tkinter can use.
canvas = turtle.getcanvas()  # Get the tkinter Canvas of this TurtleScreen.
# Create a Canvas image object holding the tkinter image.
img_obj_id = canvas.create_image(0, 0, image=tk_img, anchor='center')

为什么不直接将您的背景图片从外部转换为 GIF 并简单地执行以下操作:

screen.bgpic("eightLane.gif")

以下内容表明您缺少数据结构:

addk=0
addkk=0
addkkk=0
addkkkk=0
addkkkkk=0
addkkkkkk=0
addkkkkkkk=0
addkkkkkkkk=0

如果我们要将赛道扩展到九个车道,您的代码应该只有少数地方需要更改。我的例子:

from turtle import Screen, Turtle
from math import sin, cos, atan2, pi
from random import randrange

# should probably calculate starting positions based on ellipse perimeter
LINEUP = [  # (color, (starting postion))
    ('red', (0, 90)),
    ('yellow', (-55, 120)),
    ('blue', (-120, 150)),
    ('green', (-195, 165)),
    ('dark goldenrod', (-270, 180)),
    ('blue violet', (-365, 170)),
    ('magenta', (-465, 140)),
    ('light slate gray', (-550, 100)),
]

DELTA = 0.4  # radians clockwise

def radii(index):  # calculate concentric ellipse radii
    return 265 + index * 44, 90 + index * 36

def race():
    """
    every 1/10th of a second, pick a random
    racer and move it forward a bit
    """

    index = randrange(len(racers))
    racer = racers[index]

    # get angle from x, y; bump angle; compute new x, y
    theta = atan2(racer.ycor(), racer.xcor()) + DELTA

    a, b = radii(index)

    x = a * cos(theta)
    y = b * sin(theta)

    racer.setheading(racer.towards(x, y))
    racer.setposition(x, y)

    # check if racer has crossed the finish line
    if pi/2 < theta < pi/2 + DELTA/2:
        pass  # we have a winner!
    else:
        screen.ontimer(race, 100)

screen = Screen()
screen.setup(1225, 825)  # fit image
screen.bgpic("eightLane.gif")  # convert image to GIF for simplicity

racers = []

for index, (color, position) in enumerate(LINEUP):

    racer = Turtle('turtle', visible=False)
    racer.setheading(180 + index * 10)
    racer.speed('fastest')
    racer.color(color)
    racer.penup()
    racer.setposition(position)
    racer.showturtle()

    racers.append(racer)

race()
screen.mainloop()