Я пытаюсь закодировать программу, которая запускает и останавливает черепашку, нажимая клавишу пробела. Я получил код, чтобы начать движение черепахи, но он не останавливается, когда я нажимаю ее снова. Кажется, просто увеличить скорость. Вот мои требования к кодированию и код, который я напечатал.

Создайте программу для черепах с тремя функциями для управления черепахой. Создайте функцию под названием 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
David William 24 Апр 2017 в 18:03

2 ответа

Лучший ответ

Вы поняли это почти правильно, за исключением мелких деталей, которые нужно изменить. Глобальная переменная state_num определяет в функции advance_state_machine(), должна ли черепаха двигаться или нет. Вы получили правильную логику для поворотов, так почему бы не применить ту же логику для движения / паузы?

В своем исходном коде вы просто переключали каждый показанный кадр значения глобальной переменной из одного состояния в другое, и с помощью клавиши ПРОБЕЛ вы запустили еще один экземпляр 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 * операторы импорта, так как они предоставляют огромное количество доступных методов и переменных, которые «невидимы», потому что вы не можете напрямую видеть, откуда они берутся, НО ... имея ВСЕ код в таком коротком блоке разве не стоит?

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
Claudio 24 Апр 2017 в 21:37

То, как переменные состояния state_num и / или should_move используются выше, может рассматриваться как избыточное с собственным предикатом 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()
1
cdlane 24 Апр 2017 в 20:41
43591581