乌龟撞墙后不会回头
Turtle won't turn around after hitting a wall
我这样做是为了让乌龟绘制一个 200x200 的盒子,然后在里面弹跳。但问题是它不会从顶壁或左壁反弹。
t = turtle.Turtle()
s = turtle.Screen()
t.speed(1)
for i in range(4):
t.forward(200)
t.left(90)
t.penup()
t.goto(4, 4)
t.seth(r.randint(1, 89))
while 200 > t.xcor() > 0 and 200 > t.ycor() > 0:
if t.xcor() >= 197:
t.right(200)
if t.xcor() <= 3:
t.seth(r.randint(t.heading(),180))
if t.ycor() >= 197:
t.seth(r.randint(t.heading(), 180))
if t.ycor() <= 3:
t.left(200)
t.forward(1)
此代码允许乌龟从右墙和底部的墙上反弹。当它到达左侧或顶部墙壁时,乌龟转向屏幕左侧并继续离开屏幕。我尝试了 setHeading()
的随机数,还尝试使用 left()
和 right()
来控制乌龟撞墙时的行为。我在这里做错了什么?或者让乌龟离开墙壁的更好方法是什么?
不同的解释:乌龟撞到左墙和上墙时没有掉头,为什么?我该如何解决?
事实证明我的数字有点偏差,seth()
或 setHeading()
实际上可以达到 360。所以当我 random.randint(heading(), 180)
它可能无法找到一个值如果 heading()
大于 180。这些修改解决了我的问题。
if t.xcor() >= 195:
t.seth(150)
if t.xcor() <= 5:
t.seth(r.randint(t.heading(),310))
if t.ycor() >= 195:
t.seth(r.randint(t.heading(), 300))
if t.ycor() <= 5:
t.left(150)
现在您已经解决了问题,让我们修复您的代码。当你这样写一个循环时:
while 200 > t.xcor() > 0 and 200 > t.ycor() > 0:
if t.xcor() >= 195:
你实际上是在创建一个无限循环,因为内部逻辑阻止了 while
条件成为 False
。就好像你说 while True:
。但是你永远不应该在像 turtle 这样的事件驱动环境中说 while True:
,因为你可以屏蔽其他事件和可能性。
让我们重写您的代码,使其完全由事件驱动,并以屏幕为中心:
from turtle import Turtle, Screen
from random import randint
screen = Screen()
turtle = Turtle()
turtle.speed('fastest')
turtle.penup()
turtle.goto(-100, -100)
turtle.pendown()
for _ in range(4):
turtle.forward(200)
turtle.left(90)
turtle.penup()
turtle.home()
turtle.setheading(randint(0, 360))
def move():
if -90 < turtle.xcor() < 90 and -90 < turtle.ycor() < 90:
pass # I hate 'if's like this but it's simpler than the alternative
else:
turtle.setheading(turtle.heading() + 180 + randint(-45, 45))
turtle.forward(1) # extra bump forward to get out of trouble
turtle.forward(1)
screen.ontimer(move, 25)
move()
screen.mainloop()
不完美,但你可以看到它得到了你想要的动作,而没有锁定你可能想要发生的其他事情(比如键盘事件,通过点击关闭 window 等)
我这样做是为了让乌龟绘制一个 200x200 的盒子,然后在里面弹跳。但问题是它不会从顶壁或左壁反弹。
t = turtle.Turtle()
s = turtle.Screen()
t.speed(1)
for i in range(4):
t.forward(200)
t.left(90)
t.penup()
t.goto(4, 4)
t.seth(r.randint(1, 89))
while 200 > t.xcor() > 0 and 200 > t.ycor() > 0:
if t.xcor() >= 197:
t.right(200)
if t.xcor() <= 3:
t.seth(r.randint(t.heading(),180))
if t.ycor() >= 197:
t.seth(r.randint(t.heading(), 180))
if t.ycor() <= 3:
t.left(200)
t.forward(1)
此代码允许乌龟从右墙和底部的墙上反弹。当它到达左侧或顶部墙壁时,乌龟转向屏幕左侧并继续离开屏幕。我尝试了 setHeading()
的随机数,还尝试使用 left()
和 right()
来控制乌龟撞墙时的行为。我在这里做错了什么?或者让乌龟离开墙壁的更好方法是什么?
不同的解释:乌龟撞到左墙和上墙时没有掉头,为什么?我该如何解决?
事实证明我的数字有点偏差,seth()
或 setHeading()
实际上可以达到 360。所以当我 random.randint(heading(), 180)
它可能无法找到一个值如果 heading()
大于 180。这些修改解决了我的问题。
if t.xcor() >= 195:
t.seth(150)
if t.xcor() <= 5:
t.seth(r.randint(t.heading(),310))
if t.ycor() >= 195:
t.seth(r.randint(t.heading(), 300))
if t.ycor() <= 5:
t.left(150)
现在您已经解决了问题,让我们修复您的代码。当你这样写一个循环时:
while 200 > t.xcor() > 0 and 200 > t.ycor() > 0:
if t.xcor() >= 195:
你实际上是在创建一个无限循环,因为内部逻辑阻止了 while
条件成为 False
。就好像你说 while True:
。但是你永远不应该在像 turtle 这样的事件驱动环境中说 while True:
,因为你可以屏蔽其他事件和可能性。
让我们重写您的代码,使其完全由事件驱动,并以屏幕为中心:
from turtle import Turtle, Screen
from random import randint
screen = Screen()
turtle = Turtle()
turtle.speed('fastest')
turtle.penup()
turtle.goto(-100, -100)
turtle.pendown()
for _ in range(4):
turtle.forward(200)
turtle.left(90)
turtle.penup()
turtle.home()
turtle.setheading(randint(0, 360))
def move():
if -90 < turtle.xcor() < 90 and -90 < turtle.ycor() < 90:
pass # I hate 'if's like this but it's simpler than the alternative
else:
turtle.setheading(turtle.heading() + 180 + randint(-45, 45))
turtle.forward(1) # extra bump forward to get out of trouble
turtle.forward(1)
screen.ontimer(move, 25)
move()
screen.mainloop()
不完美,但你可以看到它得到了你想要的动作,而没有锁定你可能想要发生的其他事情(比如键盘事件,通过点击关闭 window 等)