使用空格键启动和停止Python龟

时间:2017-04-24 15:03:00

标签: python python-3.x turtle-graphics

我正在尝试通过按空格键来编写启动和停止乌龟的程序。我得到了启动乌龟移动的代码但是当我再次按下它时它不会停止它。它似乎只是提高了速度。这是我的编码要求和我输入的代码。

使用三个函数创建一个用于控制乌龟的乌龟程序。创建一个名为turnLeft的函数,当按下键盘上的右箭头时,该函数将乌龟向左旋转90度。创建一个名为turnRight的函数,在按下右箭头时将乌龟旋转90度。创建第三个函数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)

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()

2 个答案:

答案 0 :(得分:1)

除了一些微小的细节外,你几乎没有改变它。如果乌龟移动与否,全局变量state_numadvance_state_machine()函数中决定。你有合适的转弯逻辑,那么为什么不对移动/暂停应用相同的逻辑呢?

在原始代码中,您只是将每个显示的帧的全局变量值从一个状态切换到另一个状态,并使用SPACE键启动另一个advance_state_machine()实例,这使得龟更快。乌龟变得更快,因为每个SPACE在advance_state_machine()中实现的另一个循环开始与现有的循环并行运行。

在下面的代码中,函数movementControl()将boolean 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代码更多地修改为简约版本,并且也摆脱了movingControl()函数。

我个人不喜欢使用from turtle import *种导入语句,因为它们提供了大量可用的方法和变量,这些方法和变量是"隐藏的"因为你不能直接看到它们来自哪里,但是......在如此短的时间内拥有所有代码并不值得吗?

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()

答案 1 :(得分:1)

上面使用的状态变量state_num和/或should_move的方式可以被视为与turtle自己的isdown()谓词一样多余。我已经相应地重写了克劳迪奥的解决方案,但却使其极简主义,因此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()