当我点击背景时如何让Python龟识别?

时间:2018-06-09 06:44:50

标签: python python-3.x turtle-graphics

我试图制作一个游戏,你点击一堆随机圆圈并得到一个分数,但我也希望它在你错过圆圈时从你的分数中扣除。我一直试图使用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()

1 个答案:

答案 0 :(得分:0)

问题在于这一行:

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()