【问题标题】:Start and stop Python turtle with space bar使用空格键启动和停止 Python 乌龟
【发布时间】:2017-04-24 15:03:00
【问题描述】:

我正在尝试编写一个通过按空格键来启动和停止海龟的程序。我得到了启动乌龟移动的代码,但是当我再次按下它时它并没有停止它。它似乎只是增加速度。这是我的编码要求和我输入的代码。

用三个函数创建一个海龟程序来控制海龟。创建一个名为 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()

【问题讨论】:

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


    【解决方案1】:

    除了需要更改的一些小细节之外,您几乎做对了。全局变量state_numadvance_state_machine() 函数中决定海龟是否应该移动。你得到了正确的转弯逻辑,那么为什么不对移动/暂停应用相同的逻辑呢?

    在您的原始代码中,您只是将每个显示的帧中的全局变量值从一种状态切换到另一种状态,并使用 SPACE 键启动了另一个 advance_state_machine() 实例,这使海龟更快。乌龟变得更快,因为每个空间都在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 代码修改为更简约的版本,并且也去掉了 motionControl() 函数。

    我个人不喜欢使用 from turtle import * 类型的 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()
    

    【讨论】:

    • 此外,将 state_num 重命名为 should_draw 并将其设为布尔值可以使代码更易于阅读,并且切换开关变为单线:should_draw = not should_draw
    • 谢谢@Claudio 和 9000 你们都很棒......我对编码和 python 非常陌生,这个让我很兴奋。这很完美。另一个问题,是否可以将 'def motionControl():' 和 'def advance_state_machine():' 组合成一个函数?
    • @DavidWilliam:我不这么认为,您需要在不同的时间致电advance_state_machinemovementControl。 (另外,为了保持一致性,让它们都为驼峰式或下划线大小写。)
    • 哦,伙计,谢谢@9000 好消息。我从另一个程序中借用了这段代码的一部分,却忘了修复它。是的,克劳伊多,我仍在学习并试图理解 python 的所有概念(我想继续学习其他概念),并试图弄清楚一切。这个网站帮了我很大的忙,到目前为止我喜欢编程,迫不及待想了解更多信息并成为更好的编码员
    • 一些代码注释:不需要`Advance_state_machine()`中的global should_move;当你可以做wn.onkey(wn.bye, "q")时,为什么还要保留exitWindow()。最后,从技术上讲,您不需要should_move,我将在单独的答案中介绍。
    【解决方案2】:

    上面使用状态变量state_num 和/或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()
    

    【讨论】:

      猜你喜欢
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-09
      相关资源
      最近更新 更多