我试图制作一个游戏,你点击一堆随机圆圈并得到一个分数,但我也希望它在你错过圆圈时从你的分数中扣除。我一直试图使用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()
答案 0 :(得分:0)
问题在于这一行:
screen.onclick(deletescore())
它位于错误的位置(只需要调用一次,而不是在循环中)并且参数不正确,它应该传递函数而不是调用它:
screen.onclick(deletescore)
修复是多方面的:首先,将修改后的语句移到while True:
语句之前。然后修复deletescore()
的定义,以获取我们不会使用的x
和y
个参数,但这些参数必须是点击处理程序。 (或者将其包裹在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()