Перемещение черепахи по клавишам со стрелками

Я пытаюсь заставить свою черепаху двигаться в соответствии со стрелками на клавиатуре. Кто-нибудь знает, как заставить черепаху в python 3.2.2 двигаться в соответствии с командой моих клавиш со стрелками? Кстати, моя черепаха в форме танка, если это на что-то влияет. Вот мой код:

import turtle

unVar1 = 25
unVar2 = 100
unVar3 = 90
unVar4 = 150
unVar5 = -30
unVar6 = 75
unVar7 = 50
def polySquare(t, x, y, length):
    t.goto(x, y)
    t.setheading(270)

    t.begin_poly()

    for count in range(4):
        t.forward(length)
        t.left(90)

    t.end_poly()

    return t.get_poly()

def polyRectangle(t, x, y, length1, length2):
    t.goto(x, y)
    t.setheading(270)

    t.begin_poly()

    for count in range(2):
        t.forward(length1)
        t.left(90)
        t.forward(length2)
        t.left(90)

    t.end_poly()

    return t.get_poly()

def tankCursor():

    """
    Create the tank cursor.  An alternate solution is to toss the temporary turtle
    and use the commented out polygon assignments instead of the poly function calls
    """

    temporary = turtle.Turtle()

    screen = turtle.getscreen()

    delay = screen.delay()

    screen.delay(0)

    temporary.hideturtle()
    temporary.penup()

    tank = turtle.Shape("compound")

    # tire1 = ((10, unVar1), (10, unVar1 - unVar6), (10 + 30, unVar1 - unVar6), (10 + 30, unVar1))
    tire1 = polyRectangle(temporary, 10, unVar1, unVar6, 30)  # Tire #1
    tank.addcomponent(tire1, "gray", "black")

    # tire2 = ((110, unVar1), (110, unVar1 - unVar6), (110 + 30, unVar1 - unVar6), (110 + 30, unVar1))
    tire2 = polyRectangle(temporary, 110, unVar1, unVar6, 30)  # Tire #2
    tank.addcomponent(tire2, "gray", "black")

    # tire3 = ((110, unVar2), (110, unVar2 - unVar6), (110 + 30, unVar2 - unVar6), (110 + 30, unVar2))
    tire3 = polyRectangle(temporary, 110, unVar2, unVar6, 30)  # Tire #3
    tank.addcomponent(tire3, "gray", "black")

    # tire4 = ((10, unVar2), (10, unVar2 - unVar6), (10 + 30, unVar2 - unVar6), (10 + 30, unVar2))
    tire4 = polyRectangle(temporary, 10, unVar2, unVar6, 30)  # Tire #4
    tank.addcomponent(tire4, "gray", "black")

    # bodyTank = ((20, unVar3), (20, unVar3 - 130), (20 + 110, unVar3 - 130), (20 + 110, unVar3))
    bodyTank = polyRectangle(temporary, 20, unVar3, 130, 110)
    tank.addcomponent(bodyTank, "black", "gray")

    # gunTank = ((65, unVar4), (65, unVar4 - 100), (65 + 20, unVar4 - 100), (65 + 20, unVar4))
    gunTank = polyRectangle(temporary, 65, unVar4, 100, 20)   # Gun
    tank.addcomponent(gunTank, "black", "gray")

    # exhaustTank = ((50, unVar5), (50, unVar5 - 20), (50 + 10, unVar5 - 20), (50 + 10, unVar5))
    exhaustTank = polyRectangle(temporary, 50, unVar5, 20, 10)
    tank.addcomponent(exhaustTank, "black", "gray")

    # turretTank = ((50, unVar7), (50, unVar7 - 50), (50 + 50, unVar7 - 50), (50 + 50, unVar7))
    turretTank = polySquare(temporary, 50, unVar7, 50)  # Turret
    tank.addcomponent(turretTank, "red", "gray")

    turtle.addshape("tank", shape=tank)

    del temporary

    screen.delay(delay)

tankCursor()  # creates and registers the "tank" cursor shape

turtle.shape("tank")

turtle.up()  # get rid of the ink

# show our tank in motion
while True:
    turtle.forward(100)
    turtle.left(90)
    turtle.forward(100)
    turtle.left(180)
    turtle.forward(200)

person bertrand    schedule 15.03.2016    source источник
comment
извините, если мой английский не в точку   -  person bertrand    schedule 15.03.2016
comment
Вы хоть прочитали, что такое [черепаха], прежде чем пометить ею свой вопрос? Если нет, прочитайте stackoverflow.com/tags/turtle/info.   -  person Bhargav Rao    schedule 15.03.2016
comment
Ой. Я не знал этого. Я думал, что «черепаха» означает функцию рисования Python. Спасибо за информацию.   -  person bertrand    schedule 16.03.2016


Ответы (1)


Вы можете использовать встроенные в черепаху обработчики ключевых событий. Это ссылка на документы: https://docs.python.org/3.2/library/turtle.html

Используя ваш код, все остается неизменным до tankCursor() (строка 98). Теперь по порядку, вот что я сделал.

tankCursor()  # creates and registers the "tank" cursor shape

tank = turtle
tank.shape("tank")

turtle.up()  # get rid of the ink

screen = turtle.Screen()

Я сделал переменную резервуара, чтобы вы взаимодействовали с ней (вы использовали черепаху.foward, черепаху.назад и т. д.), а не черепаху. Просто хорошая практика, и теперь вы можете иметь несколько танков на экране или несколько персонажей, если хотите. turtle.up() взято из вашего исходного кода. screen = turtle.Screen() означает, что ваш код получает уведомления о ключевых событиях, т.е. когда пользователь нажимает клавишу/отпускает клавишу.

def moveright():
    tank.forward(40)

def moveleft():
    tank.backward(40) 

Это всего лишь функции для перемещения танка вправо и влево. Обратите внимание, что я использовал tank.forward, а не черепаху.forward. Это соответствует переменной tank = turtle выше. Имя «танк» может быть любым, просто убедитесь, что вы используете это имя во всем коде. Функции .forward и .backward того же типа, что вы использовали в

while True:
    turtle.forward(100)
    turtle.left(90)
    turtle.forward(100)
    turtle.left(180)
    turtle.forward(200)

все это должно работать и в функциях moveright/moveleft.

screen.onkeypress(moveright, "Right")
screen.onkeypress(moveleft, "Left")

screen.listen()
screen.mainloop()

Теперь магия. 2 строки screen.onkeypress сообщают компьютеру о необходимости прослушивания нажатой клавиши. Он принимает 2 аргумента, первый — это функция (то есть части moveright, moveleft), а второй аргумент — это строка, относящаяся к нужной клавише на клавиатуре. Например. 'e' -> клавиша 'e', ​​'w' -> буква w, -> 'Вверх' -> стрелка вверх -> 'Вправо' -> стрелка вправо, и так далее, и так далее. **Имена клавиш должны быть в кавычках, как в примере выше. если вы сделаете screen.onkeypress(moveright, Right), это выдаст ошибку.

screen.listen() приказывает компьютеру начать список ключевых событий, а screen.mainloop запускает основной цикл Черепахи, так что он продолжает поиск, пока не будет вызвано turtle.done(). screen.mainloop очень важен, потому что без него ваша программа завершилась бы и никакие события не были бы получены.

Вот полный код, не стесняйтесь копировать/вставлять и использовать его по своему усмотрению. Опять же, код продолжается с tankCursor(), строка 98.

tankCursor()  # creates and registers the "tank" cursor shape

tank = turtle
tank.shape("tank")

turtle.up()  # get rid of the ink

screen = turtle.Screen()

def moveright():
    tank.forward(40)

def moveleft():
    tank.backward(40)

screen.onkeypress(moveright, "Right")
screen.onkeypress(moveleft, "Left")

screen.listen()
screen.mainloop()
person Mark Dodds    schedule 15.03.2016
comment
Большое спасибо за подробный и содержательный ответ - person bertrand; 16.03.2016