正在尝试用 Turtle 从 window 墙上反弹

Attempting to bounce off window wall with Turtle

该程序可以运行,但是当它撞到墙上时,乌龟撤消了最后一步并重试。然而,它一直输入相同的前向距离和角度,导致它在循环中以相同的路径移动。有没有办法阻止乌龟再次取相同的值?

from turtle import Turtle, Screen
import random

def createTurtle(color, width):
    tempName = Turtle("arrow")
    tempName.speed("fastest")
    tempName.color(color)
    tempName.width(width)
    return tempName

def inScreen(screen, turt):

    x = screen.window_width() / 2
    y = screen.window_height() / 2

    turtleX, turtleY = turt.pos()

    if not (-x < turtleX < x) and (-y < turtleY < y):
        return False
    return True

def moveTurtle(screen, turt):

    while True:
        while inScreen(screen, turt):
            turt.fd(random.randrange(100))
            turt.left(random.randrange(360))
        if (inScreen(screen, turt) == False):
            turt.undo()
            continue

wn = Screen()
alpha = createTurtle("red", 3)
moveTurtle(wn, alpha)
wn.exitonclick()

我不认为它一直在同一条道路上前进。我试过 运行 你的代码,它一直给乌龟一个新的前向量和旋转。如果你等得够久,它最终会离开那个地方。

它似乎没有在原地移动的原因是它一直在尝试去到一个新的地点,但它很有可能会选择一个随机值,再次将乌龟置于屏幕边界之外.

如果乌龟超出范围,我可能会将其引导到范围的相反角度方向,因为现在它只是重复选择随机值。

我认为你的代码的问题是这个逻辑:

while inScreen(screen, turt):
    turt.fd(random.randrange(100))
    turt.left(random.randrange(360))
if (inScreen(screen, turt) == False):
    turt.undo()

当您调用 undo() 时,您只是撤消了最后发生的事情,因此您撤消了 left() 而不是 fd()(向前)。如果出错,您会在屏幕外越走越远,并且需要更长的时间才能返回。如果我们撤消这两个操作(两次 undo() 调用),或者颠倒操作顺序并仅撤消前向操作,那么您的随机运动将更快地自我纠正。无需调整标题。

这里对您的代码进行了修改以修复上述问题,并消除不属于 event-driven 程序并使 exitonclick() 无法正常工作的 while True: 逻辑:

from turtle import Turtle, Screen
import random

def createTurtle(color, width):
    turtle = Turtle('arrow')
    turtle.speed('fastest')
    turtle.color(color)
    turtle.width(width)

    return turtle

def inScreen(screen, turtle):

    x = screen.window_width() / 2
    y = screen.window_height() / 2

    turtleX, turtleY = turtle.pos()

    return (-x < turtleX < x) and (-y < turtleY < y)

def moveTurtle():

    turtle.left(random.randrange(360))
    turtle.forward(random.randrange(100))

    if not inScreen(screen, turtle):
        turtle.undo()  # undo forward()

    screen.ontimer(moveTurtle, 50)

screen = Screen()
turtle = createTurtle('red', 3)
moveTurtle()
screen.exitonclick()

请注意,您现在可以随时单击屏幕退出。使用您的原始代码,点击屏幕对我的系统没有任何反应。