首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >让TKinter跟踪鼠标对对象的移动时出现问题

让TKinter跟踪鼠标对对象的移动时出现问题
EN

Stack Overflow用户
提问于 2015-02-27 09:23:27
回答 1查看 108关注 0票数 0

我不确定是否要发布完整的代码,但以下是我所拥有的:

代码语言:javascript
复制
from tkinter import *
from random import randint

HEIGHT = 500
WIDTH = 800

MID_X = WIDTH/2
MID_Y = HEIGHT/2

SHIP_R = 15
SHIP_SPD = 10

bub_id = list()
bub_r = list()
bub_speed = list()

MIN_BUB_R = 10
MAX_BUB_R = 30
MAX_BUB_SPD = 6

GAP = 100

window = Tk()
window.title('Bubble Blaster')

c = Canvas(window, width=WIDTH, height=HEIGHT, bg='darkblue')
c.pack()

ship_id = c.create_polygon(5, 5, 5, 25, 30, 15, fill='red')
ship_id2 = c.create_oval(0, 0, 30, 30, outline='red')

c.move(ship_id, MID_X, MID_Y)
c.move(ship_id2, MID_X, MID_Y)



def move_ship(event):
    fixed = True
    while fixed == True:
        ship_x, ship_y = event.x, event.y
        c.move(ship_id, ship_x, ship_y)
        c.move(ship_id2, ship_x, ship_y)
        sleep(0.01)



def create_bubble():
    x = WIDTH + GAP
    y = randint(0, HEIGHT)
    r = randint(MIN_BUB_R, MAX_BUB_R)
    id1 = c.create_oval(x-r, y-r, x+r, y+r, outline='white')
    bub_id.append(id1)
    bub_r.append(r)
    bub_speed.append(randint(1, MAX_BUB_SPD))

def move_bubbles():
    for i in range(len(bub_id)):
        c.move(bub_id[i], -bub_speed[i], 0)

def get_coords(id_num):
    pos = c.coords(id_num)
    x = (pos[0] + pos[2])/2
    y = (pos[1] + pos[3])/2
    return x, y

def del_bubble(i):
    del bub_r[i]
    del bub_speed[i]
    c.delete(bub_id[i])
    del bub_id[i]

def clean_up_bubs():
    for i in range(len(bub_id)-1, -1, -1):
        x, y = get_coords(bub_id[i])
        if x < -GAP:
            del_bubble(i)

from math import sqrt

def distance(id1, id2):
    x1, y1 = get_coords(id1)
    x2, y2 = get_coords(id2)
    return sqrt((x2-x1)**2 + (y2-y1)**2)

def collision():
    points = 0
    for bub in range(len(bub_id)-1, -1, -1):
        if distance(ship_id2, bub_id[bub]) < (SHIP_R+bub_r[bub]):
            points += (bub_r[bub] + bub_speed[bub])
            del_bubble(bub)
    return points

c.create_text(50, 30, text='TIME', fill='white')
c.create_text(150, 30, text='SCORE', fill='white')

time_text = c.create_text(50, 50, fill='white')
score_text = c.create_text (150, 50, fill='white')

def show_score(score):
    c.itemconfig(score_text, text=str(score))

def show_time(time_left):
    c.itemconfig(time_text, text=str(time_left))

from time import sleep, time
BUB_CHANCE = 20
TIME_LIMIT = 30
BONUS_SCORE = 1000

# MAIN GAME LOOP
c.bind("<B1_Motion>", move_ship)
score = 0
bonus = 0
end = time() + TIME_LIMIT

while time() < end:
    if randint(1, BUB_CHANCE) == 1:
        create_bubble()
    move_bubbles()
    move_ship("<B1_Motion>")
    clean_up_bubs()
    score += collision()
    if (int(score / BONUS_SCORE)) > bonus:
        bonus += 1
        end += TIME_LIMIT
    show_score(score)
    show_time(int(end-time()))
    window.update()
    sleep(0.01)

c.create_text(MID_X, MID_Y, \
    text='PARTY TIME, EXCELLENT', fil='white', font=('Helvetica', 30))
c.create_text(MID_X, MID_Y + 30, \
    text='Score: ' + str(score), fill='white')
c.create_text(MID_X, MID_Y + 45, \
    text='BONU TIME: ' + str(bonus*TIME_LIMIT), fill='white')

我似乎就是不能正确地理解它。如有任何建议,我们将不胜感激!

EN

回答 1

Stack Overflow用户

发布于 2015-02-28 21:12:47

第一步是删除while循环,并将大部分功能放入一个函数中。把你想做的每件事都放在动画的一帧里。

接下来,使用after命令定期调用此函数。这允许事件循环连续运行,这对您的UI响应非常重要。您可以在此函数中进行time() < end计算,并在时间用完后使用结果来中断循环。

它看起来像这样:

代码语言:javascript
复制
def draw_one_frame():
    if randint(1, BUB_CHANCE) == 1:
        create_bubble()
    move_bubbles()
    # move_ship("<B1_Motion>")
    clean_up_bubs()
    score += collision()
    if (int(score / BONUS_SCORE)) > bonus:
        bonus += 1
        end += TIME_LIMIT
    show_score(score)
    show_time(int(end-time()))

    if time() < end:
        after(10, draw_one_frame)

您可以使用after的第一个参数来控制您希望程序每秒运行的帧数。

接下来,您需要处理鼠标移动。您可以通过创建鼠标移动的绑定来完成此操作。您可以在draw_one_frame方法之外执行此操作。它看起来像这样:

代码语言:javascript
复制
c.bind("<B1-Motion>", move_ship)

您还需要从move_ship中删除无限循环,并删除休眠。您只需完成当前鼠标位置的所有计算。该函数已经在循环了--每次鼠标移动时都会调用一次。

最后,您需要在所有其他代码之后调用window.mainloop(),以便程序可以处理事件。这应该是你程序的最后一行。它将一直运行,直到窗口被销毁。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28755971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档