Я согласен с @furas (+1) о том, как настроить ontimer(timer_go, 100)
, но я вижу другие проблемы с вашим кодом. Я переделал это ниже, и я надеюсь, что вы найдете некоторые изменения полезными.
Конкретные проблемы: вам нужно (пере) прочитать примерно global
как половину времени, когда вы используете его неправильно; вам не нужно заново изобретать turtle.distance()
(например, в is_touch()
); вам нужно отделить playing == False
от неудачи, так как вам нужно остановить игру в случае успеха или неудачи; Вам нужно только указать количество треугольников в одном месте:
from turtle import Screen, Turtle
from random import randint, choice
FONT = ('Arial', 16, 'normal')
def draw_square(turtle, distance=400): # Draw a box
turtle.speed('fastest')
turtle.penup()
turtle.goto(-200, 200)
turtle.pendown()
for _ in range(4):
turtle.forward(distance)
turtle.right(90)
def add_triangle():
triangle = Turtle("triangle")
triangle.penup()
triangle.goto(choice([(choice([-150, 150]), randint(-150, 150)), (randint(-150, 150), choice([-150, 150]))]))
triangle.setheading(randint(-89, 89))
# make triangle and start
triangles.append(triangle) # add a triangle to list
def successMan(): # write word success
global playing
if playing:
player.write("Success!", font=FONT)
playing = False
def turn_right():
global right
right = True
def turn_left():
global left
left = True
def turn_up():
global up
up = True
def turn_down():
global down
down = True
def _turn_right():
global right
right = False
def _turn_left():
global left
left = False
def _turn_up():
global up
up = False
def _turn_down():
global down
down = False
def is_touch(player, triangle, threshold=20):
return player.distance(triangle) < threshold
def timer_go():
global playing
heading = player.heading()
if up:
if right:
heading = 45
elif left:
heading = 135
elif down:
pass
else:
heading = 90
if down:
if right:
heading = 315
elif left:
heading = 225
elif up:
pass
else:
heading = 270
if left:
if right:
pass
elif up:
pass
elif down:
pass
else:
heading = 180
if right:
if left:
pass
elif up:
pass
elif down:
pass
else:
heading = 0
player.setheading(heading)
player.forward(10)
# turtle controller
for triangle in triangles: # triangles move
x, y = triangle.position()
if not -200 < x < 200:
triangle.setheading(180 - triangle.heading())
triangle.forward(10)
if not -200 < y < 200:
triangle.setheading(-triangle.heading())
triangle.forward(10)
triangle.forward(10)
# check triangle and turtle
if is_touch(player, triangle, threshold=20):
playing = False
player.write("FAIL!", font=FONT) # Fail
if playing:
screen.ontimer(timer_go, 100)
up = False
down = False
right = False
left = False
playing = True
triangles = []
draw_square(Turtle(visible=False))
for _ in range(3):
add_triangle()
player = Turtle('turtle')
player.speed('fastest')
screen = Screen()
screen.onkeypress(turn_right, 'Right')
screen.onkeypress(turn_left, 'Left')
screen.onkeypress(turn_up, 'Up')
screen.onkeypress(turn_down, 'Down')
screen.onkeyrelease(_turn_right, 'Right')
screen.onkeyrelease(_turn_left, 'Left')
screen.onkeyrelease(_turn_up, 'Up')
screen.onkeyrelease(_turn_down, 'Down')
screen.ontimer(successMan, 20_000)
timer_go()
screen.listen()
screen.mainloop()
Я подозреваю, что ваш RecursionError
связан с вашими ключевыми событиями, так как ваша модель может показывать, что несколько ключей могут выйти из строя одновременно. Но если ключ удерживается слишком долго, он может вызвать ключевое событие внутри ключевого события, и это выглядит как рекурсия. Обычно это можно исправить, отключив обработчик события ключа в качестве первого элемента в обработчике события, выполнив свою работу, а затем снова включив обработчик события ключа.
Однако у вас также может быть логика автоматического повторения клавиш, управляемая ОС. Если ваша обработка ключей оказывается проблемой, попробуйте использовать более простой подход.