使用 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_numadvance_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()