Start and stop Python turtle with space bar

假如想象 提交于 2020-01-04 09:36:07

问题


I am trying to code a program that starts and stops a turtle by pressing the space bar. I got the code to start the turtle moving but it doesn't stop it when I press it again. It seems to just increase the speed. Here are my coding requirements and the code I typed up.

Create a turtle program with three functions to control the turtle. Create a function called turnLeft that turns the turtle 90 degrees left when the right arrow is pressed on the keyboard. Create a function called turnRight that turns the turtle 90 degrees right when the right arrow is pressed. Create a third function called move() that moves the turtle forward when the space bar is pressed, then stops the turtle when the spacebar is pressed a second time.

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

回答1:


You got it almost right except some tiny details to change. The global variable state_num decided in the advance_state_machine() function if the turtle should move or not. You got the proper logic for the turns, so why not apply the same logic for a move/pause ?

In your original code you were just switching each shown frame the global variable value from one state to another and with the SPACE key you started another instance of advance_state_machine() what made the turtle faster. The turtle got faster because with each SPACE a further loop implemented in advance_state_machine() was started to run in parallel to the existing one(s).

In the code below the function movementControl() changes the value of boolean should_move to the opposite one on SPACE and the advance_state_machine() evaluates should_move to let the turtle move or stop:

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

Wow!!! With cdlane's help we put here a really nice basic turtle example together.

Now I have modified HIS code a bit more towards a minimalistic version and got rid of the movementControl() function, too.

I personally don't like to use from turtle import * kind of import statements as they provide a huge number of available methods and variables which are "invisible" because you can't directly see where they come from, BUT ... having ALL the code in a so short block isn't it worth it?

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



回答2:


The way the state variables state_num and/or should_move are used above can be seen as redundant with turtle's own isdown() predicate. I've rewritten Claudio's solution accordingly but made it minimalist so the isdown() logic stands out:

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


来源:https://stackoverflow.com/questions/43591581/start-and-stop-python-turtle-with-space-bar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!