如何让蟒蛇龟在单击背景时识别?



我正在尝试制作一个游戏,您可以单击一堆随机圆圈并获得分数,但是当您错过圆圈时,我也希望它从您的分数中扣除。我一直在尝试使用screen.onclick()但不是在错误点击时扣除分数,而是似乎无缘无故地每秒扣除分数。我做错了什么?

import turtle
from random import random, randint
import time
CURSOR_SIZE = 20
score=0
def addscore():
global score
score += 1
def deletescore():
global score
score -= 1
def my_circle(color):
radius = (15)
circle = turtle.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.showturtle()
circle.onclick(lambda x,y,t=circle: (circle.hideturtle(), addscore()))
screen.onclick(deletescore())

return radius, circle
username=str(input("Set your username: "))
screen = turtle.Screen()
screen.bgcolor("lightgreen")
screen.title("Speed Clicker")
width, height = screen.window_width(), screen.window_height()
circles = []
gameLength = 30
difficulty = 20
startTime = time.time()
while True:
time.sleep(1/difficulty)
rgb = (random(), random(), random())
timeTaken = time.time() - startTime
circles.append(my_circle(rgb))
screen.title('SCORE: {}, TIME LEFT: {}'.format(score,int(round(gameLength - timeTaken,0))))
if time.time() - startTime > gameLength: 
break
screen.title('GG! FINAL SCORE: {}'.format(score))

screen.mainloop()

问题是这一行:

screen.onclick(deletescore())

它在错误的地方(只需要调用一次,而不是在循环中(,并且参数不正确,它应该传递函数而不调用它:

screen.onclick(deletescore)

修复是多方面的:首先,将修改后的语句移动到while True:语句之前。 然后修复deletescore()的定义,以接受我们不会使用但成为点击处理程序所必需的xy参数。 (或将其包裹在lambda中,例如调用addscore()(

但是,点击也可以作为点击屏幕传递。 为了解决这个问题,我们可以在addscore()中添加 2 而不是 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()

最新更新