使用 space 栏启动和停止 Python 乌龟
Start and stop Python turtle with space bar
我正在尝试编写一个程序,通过按 space 栏来启动和停止海龟。我得到了启动乌龟移动的代码,但是当我再次按下它时它并没有停止。好像只是提高了速度。这是我的编码要求和我输入的代码。
创建一个包含三个函数的海龟程序来控制海龟。创建一个名为 turnLeft 的函数,当按下键盘上的向右箭头时,该函数将海龟向左旋转 90 度。创建一个名为 turnRight 的函数,它在按下向右箭头时将海龟向右旋转 90 度。创建第三个名为 move() 的函数,它在按下 space 栏时使海龟向前移动,然后在第二次按下 space 栏时停止海龟。
import turtle
turtle.setup(400,500)
wn = turtle.Screen()
wn.title("Tess moves in space")
wn.bgcolor("lightgreen")
tess = turtle.Turtle()
def leftTurtle():
tess.left(90)
def rightTurtle():
tess.right(90)
state_num = 0
def advance_state_machine():
global state_num
if state_num == 0:
tess.penup()
state_num = 1
else:
tess.pendown()
tess.forward(2)
state_num = 0
wn.ontimer(advance_state_machine, 25)
def exitWindow():
wn.bye()
wn.onkey(advance_state_machine, "space")
wn.onkey(exitWindow, "q")
wn.onkey(leftTurtle, "Left")
wn.onkey(rightTurtle, "Right")
wn.listen()
wn.mainloop()
除了一些微小的细节需要更改外,你几乎做对了。全局变量 state_num
在 advance_state_machine()
函数中决定乌龟是否应该移动。你得到了正确的转弯逻辑,那么为什么不对 move/pause 应用相同的逻辑?
在您的原始代码中,您只是将每个显示的帧的全局变量值从一种状态切换到另一种状态,并使用 SPACE 键启动了另一个 advance_state_machine()
实例,这使乌龟更快。乌龟变得更快,因为每个 SPACE 中的另一个循环在 advance_state_machine()
中开始实施,与现有循环并行 运行。
在下面的代码中,函数 movementControl()
将布尔值 should_move
更改为 SPACE 上的相反值,并且 advance_state_machine()
计算 should_move
为让乌龟移动或停止:
import turtle
turtle.setup(400,500)
wn = turtle.Screen()
wn.title("Tess moves in space")
wn.bgcolor("lightgreen")
tess = turtle.Turtle()
def leftTurtle():
tess.left(90)
def rightTurtle():
tess.right(90)
should_move = False
def movementControl():
global should_move
should_move = not should_move
def advance_state_machine():
global should_move
if should_move:
tess.pendown()
tess.forward(2)
else:
tess.penup()
wn.ontimer(advance_state_machine, 25)
def exitWindow():
wn.bye()
wn.onkey(movementControl, "space")
wn.onkey(exitWindow, "q")
wn.onkey(leftTurtle, "Left")
wn.onkey(rightTurtle, "Right")
wn.listen()
advance_state_machine()
wn.mainloop()
哇!!!在 cdlane's
的帮助下,我们将一个非常好的基本海龟示例放在了一起。
现在我已经将 HIS 代码修改得更趋向于一个简约版本,并且也去掉了 movementControl() 函数。
我个人不喜欢使用 from turtle import *
类的导入语句,因为它们提供了大量可用的方法和变量,"invisible" 因为你无法直接看到它们的来源来自,但是......将所有代码放在这么短的块中是不是值得?
from turtle import *
setup(400, 500); title('Turtle moves in space')
bgcolor('lightgreen'); up()
def advance_state_machine():
if isdown(): fd(2)
ontimer(advance_state_machine, 25)
onkey(lambda: (pd, pu)[isdown()](), 'space')
onkey(bye, 'q')
onkey(lambda: lt(90), 'Left')
onkey(lambda: rt(90), 'Right')
listen(); advance_state_machine(); done()
上面使用状态变量state_num
and/or should_move
的方式可以看作是与turtle自己的isdown()
谓词的冗余。我已经相应地重写了 Claudio 的解决方案,但使其变得极简,因此 isdown()
逻辑脱颖而出:
from turtle import *
def movementControl():
(pd, pu)[isdown()]()
def advance_state_machine():
if isdown():
fd(2)
ontimer(advance_state_machine, 25)
setup(400, 500)
title('Turtle moves in space')
bgcolor('lightgreen')
up()
onkey(movementControl, 'space')
onkey(bye, 'q')
onkey(lambda: lt(90), 'Left')
onkey(lambda: rt(90), 'Right')
listen()
advance_state_machine()
done()
我正在尝试编写一个程序,通过按 space 栏来启动和停止海龟。我得到了启动乌龟移动的代码,但是当我再次按下它时它并没有停止。好像只是提高了速度。这是我的编码要求和我输入的代码。
创建一个包含三个函数的海龟程序来控制海龟。创建一个名为 turnLeft 的函数,当按下键盘上的向右箭头时,该函数将海龟向左旋转 90 度。创建一个名为 turnRight 的函数,它在按下向右箭头时将海龟向右旋转 90 度。创建第三个名为 move() 的函数,它在按下 space 栏时使海龟向前移动,然后在第二次按下 space 栏时停止海龟。
import turtle
turtle.setup(400,500)
wn = turtle.Screen()
wn.title("Tess moves in space")
wn.bgcolor("lightgreen")
tess = turtle.Turtle()
def leftTurtle():
tess.left(90)
def rightTurtle():
tess.right(90)
state_num = 0
def advance_state_machine():
global state_num
if state_num == 0:
tess.penup()
state_num = 1
else:
tess.pendown()
tess.forward(2)
state_num = 0
wn.ontimer(advance_state_machine, 25)
def exitWindow():
wn.bye()
wn.onkey(advance_state_machine, "space")
wn.onkey(exitWindow, "q")
wn.onkey(leftTurtle, "Left")
wn.onkey(rightTurtle, "Right")
wn.listen()
wn.mainloop()
除了一些微小的细节需要更改外,你几乎做对了。全局变量 state_num
在 advance_state_machine()
函数中决定乌龟是否应该移动。你得到了正确的转弯逻辑,那么为什么不对 move/pause 应用相同的逻辑?
在您的原始代码中,您只是将每个显示的帧的全局变量值从一种状态切换到另一种状态,并使用 SPACE 键启动了另一个 advance_state_machine()
实例,这使乌龟更快。乌龟变得更快,因为每个 SPACE 中的另一个循环在 advance_state_machine()
中开始实施,与现有循环并行 运行。
在下面的代码中,函数 movementControl()
将布尔值 should_move
更改为 SPACE 上的相反值,并且 advance_state_machine()
计算 should_move
为让乌龟移动或停止:
import turtle
turtle.setup(400,500)
wn = turtle.Screen()
wn.title("Tess moves in space")
wn.bgcolor("lightgreen")
tess = turtle.Turtle()
def leftTurtle():
tess.left(90)
def rightTurtle():
tess.right(90)
should_move = False
def movementControl():
global should_move
should_move = not should_move
def advance_state_machine():
global should_move
if should_move:
tess.pendown()
tess.forward(2)
else:
tess.penup()
wn.ontimer(advance_state_machine, 25)
def exitWindow():
wn.bye()
wn.onkey(movementControl, "space")
wn.onkey(exitWindow, "q")
wn.onkey(leftTurtle, "Left")
wn.onkey(rightTurtle, "Right")
wn.listen()
advance_state_machine()
wn.mainloop()
哇!!!在 cdlane's
的帮助下,我们将一个非常好的基本海龟示例放在了一起。
现在我已经将 HIS 代码修改得更趋向于一个简约版本,并且也去掉了 movementControl() 函数。
我个人不喜欢使用 from turtle import *
类的导入语句,因为它们提供了大量可用的方法和变量,"invisible" 因为你无法直接看到它们的来源来自,但是......将所有代码放在这么短的块中是不是值得?
from turtle import *
setup(400, 500); title('Turtle moves in space')
bgcolor('lightgreen'); up()
def advance_state_machine():
if isdown(): fd(2)
ontimer(advance_state_machine, 25)
onkey(lambda: (pd, pu)[isdown()](), 'space')
onkey(bye, 'q')
onkey(lambda: lt(90), 'Left')
onkey(lambda: rt(90), 'Right')
listen(); advance_state_machine(); done()
上面使用状态变量state_num
and/or should_move
的方式可以看作是与turtle自己的isdown()
谓词的冗余。我已经相应地重写了 Claudio 的解决方案,但使其变得极简,因此 isdown()
逻辑脱颖而出:
from turtle import *
def movementControl():
(pd, pu)[isdown()]()
def advance_state_machine():
if isdown():
fd(2)
ontimer(advance_state_machine, 25)
setup(400, 500)
title('Turtle moves in space')
bgcolor('lightgreen')
up()
onkey(movementControl, 'space')
onkey(bye, 'q')
onkey(lambda: lt(90), 'Left')
onkey(lambda: rt(90), 'Right')
listen()
advance_state_machine()
done()