Проблема в этой строке:
screen.onclick(deletescore())
Она не в том месте (нужно вызывать только один раз, а не в цикле), а аргумент неверен, он должен передавать функцию, не вызывающуюit:
screen.onclick(deletescore)
Исправление является многократным: сначала переместите измененный оператор непосредственно перед вашим оператором while True:
.Затем исправьте определение deletescore()
, чтобы принимать x
и y
аргументы, которые мы не будем использовать, но которые необходимы для обработки кликов.(Или оберните его в lambda
, как при вызове addscore()
)
Однако щелчок на черепахе также можно пропустить как щелчок на экране.Чтобы противостоять этому, мы можем добавить 2 в addscore()
вместо 1, так как deletescore()
также будет вызываться.Этого должно быть достаточно, чтобы все заработало.
Однако мы действительно должны исключить цикл while True:
и вызов sleep()
, которые не имеют места в программе, управляемой событиями.Вместо этого мы используем ontimer()
, чтобы держать вещи в движении и не блокировать другие события.Переформулированный кодекс будет больше похож на:
from turtle import Turtle, Screen
from random import random, randint
from time import time
CURSOR_SIZE = 20
def addscore():
global score
score += 2 # add 2 as this will also count as a -1 screen click!
def deletescore():
global score
score -= 1
def my_circle(color):
circle = Turtle('circle', visible=False)
circle.shapesize(radius / CURSOR_SIZE)
circle.color(color)
circle.penup()
while True:
nx = randint(2 * radius - width // 2, width // 2 - radius * 2)
ny = randint(2 * radius - height // 2, height // 2 - radius * 2)
circle.goto(nx, ny)
for other_radius, other_circle in circles:
if circle.distance(other_circle) < 2 * max(radius, other_radius):
break
else:
break
circle.onclick(lambda x, y: (circle.hideturtle(), addscore()))
circle.showturtle()
return radius, circle
def play():
rgb = (random(), random(), random())
timeTaken = time() - startTime
circles.append(my_circle(rgb))
screen.title('SCORE: {}, TIME LEFT: {}'.format(score, int(round(gameLength - timeTaken, 0))))
if time() - startTime > gameLength:
screen.title('FINAL SCORE: {}'.format(score))
screen.onclick(None)
screen.clear()
else:
screen.ontimer(play, 1000 // difficulty)
screen = Screen()
screen.bgcolor("lightgreen")
screen.title("Speed Clicker")
width, height = screen.window_width(), screen.window_height()
score = 0
circles = []
radius = 15
difficulty = 20
gameLength = 30
screen.onclick(lambda x, y: deletescore())
startTime = time()
play()
screen.mainloop()