Turtle-graphics не отвечает на команды onkey (), если активен цикл while - PullRequest
0 голосов
/ 22 февраля 2019

Я пытаюсь создать игру, в которой черепаха должна иметь возможность регистрироваться и реагировать на вводимые пользователем данные (упрощенно, появится буква, и пользователь должен щелкнуть ее на клавиатуре. Поэтому, если она показывает «b»,пользователь типа "б").Я только добавил буквы a к f, чтобы было проще во время теста.У каждого из них есть функция, которая будет выполняться, когда буква нажата, и программа прослушивает ее.

Все работало нормально, пока я не добавил функцию while.В настоящее время в функции while нет ничего (кроме pass), но после того, как я это сделал, код больше не будет реагировать на вводимые пользователем данные.Может кто-нибудь сказать мне, как это исправить?Моя конечная цель состоит в том, чтобы программа всегда прослушивала пользовательский ввод, пока цикл while работает и выполняет свой код.Ниже приведен мой текущий код

import signal, turtle

def timeout_handler(signal, frame): # End of timer function
    raise Exception('Time is up!')

signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(10) # Number inside is how long the game will last.

def hit_a():
    print("a registered")
def hit_b():
    print("b registered")
def hit_c():
    print("c registered")
def hit_d():
    print("d registered")
def hit_e():
    print("e registered")
def hit_f():
    print("f registered")

turtle.onkey(hit_a, "a")
turtle.onkey(hit_b, "b")
turtle.onkey(hit_c, "c")
turtle.onkey(hit_d, "d")
turtle.onkey(hit_e, "e")
turtle.onkey(hit_f, "f")
turtle.listen()


while True:
    pass
    # Add program here
turtle.mainloop()

РЕДАКТИРОВАТЬ: мне нужен там код или хотя бы цикл, чтобы повторять раздел.В псевдокоде это выглядит так:

Several turtles each write one letter somewhere on the screen
Program waits for user to input a letter
Award/deduct points based on if they got it right or wrong
go back to line 2 if they got it wrong.
repeat

Я планирую добавить больше вещей, но сначала мне нужно запустить базовую игру.Единственный способ узнать, как это кодировать, - использовать цикл while.Но использование одного из них представляется невозможным, поскольку оно не позволяет программе прослушивать вводимые пользователем данные.Обратите внимание, что мне нужно это все на черепахе, а не на терминале (командная строка, если на окнах), так как я буду раскрашивать буквы, чтобы показать, каких из них следует избегать, а каких вводить.Как я должен написать это?

Я также хочу быстро упомянуть, что раньше я "избегал" этой проблемы.В приведенном ниже коде программа реагирует на вводимые пользователем данные, когда находится в цикле while.(Игнорировать проблемы и назначить функции onkey (). Идея состоит в том, что программа отвечает, находясь в цикле).Тем не менее, я не могу понять, почему в этом коде программа отвечает, находясь в цикле, но в приведенном выше коде она не регистрирует какой-либо пользовательский ввод

turtle.onkey(lower_game1_number, "s")
turtle.onkey(increase_game1_number, "w")
turtle.listen(xdummy=None, ydummy=None)

while True: # game1 is a turtle
    game1.write(first_game_num_display,False,"center",("Arial",30))
    game1_timer = random.randint(2,4)
    time.sleep(game1_timer)
    increase_game1_number()
    game1.undo()
    print(game1_timer)


mainloop()

1 Ответ

0 голосов
/ 22 февраля 2019

Наряду с рекомендацией "никогда не использовать while True: в среде, основанной на событиях", предоставленной @martineau, вам не нужно перетаскивать библиотеку 'signal' в код, поскольку вы можете справиться с этим с помощью ontimer()event.

Мне нужен код while или хотя бы цикл для повторения раздела.

Для решения этой проблемы я заменил свой предыдущий пример кодас простой игрой, которая показывает букву и будет перемещать ее по экрану и менять ее цвет каждые две секунды, пока вы не наберете эту букву.После этого он изменится на другую букву и продолжит:

from turtle import Screen, Turtle
from random import shuffle, randrange
from itertools import cycle

WIDTH, HEIGHT = 600, 600

FONT_SIZE = 36
FONT = ('Arial', FONT_SIZE, 'bold')

LETTERS = list("abcdefghijklmnopqrstuvwxyz")

COLORS = ['red', 'blue', 'green', 'magenta', 'cyan', 'black', 'orange', 'gray']

def play():
    global letter

    if hit == letter:
        letter = next(letters)

    turtle.clear()
    turtle.color(next(colors))
    turtle.goto(randrange(FONT_SIZE - WIDTH/2, WIDTH/2 - FONT_SIZE), randrange(FONT_SIZE - HEIGHT/2, HEIGHT/2 - FONT_SIZE))
    turtle.write(letter, font=FONT)

    screen.ontimer(play, 2000)

letters = LETTERS
shuffle(letters)
letters = cycle(letters)
letter = next(letters)

colors = COLORS
shuffle(colors)
colors = cycle(colors)

hit = None

screen = Screen()
screen.setup(WIDTH, HEIGHT)

turtle = Turtle(visible=False)
turtle.penup()

for character in LETTERS:

    def hit_character(character=character):
        global hit

        hit = character

    screen.onkey(hit_character, character)

screen.listen()

play()

screen.mainloop()

Убедитесь, что нажали на окно, прежде чем вводить его, чтобы прослушать ввод.

Надеюсь, это дасту вас есть идеи, как решить вашу более сложную проблему без использования цикла while True:.Или, по крайней мере, покажите, как можно настроить все свои onkey() назначения событий и обработчики, не переписывая один и тот же код для каждой буквы в алфавите ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...