我开始编写Connect 4游戏的编码(点击会触发光盘掉落)我想要制作光盘动画。秋季。 所以我首先创建一个新的光盘映像:
discList[y][x] = can.create_image((xCan,yCurrent), image=imgRedDisc, anchor="nw")
光盘在xCan的画布顶部创建; yCurrent。我现在要做的是将光盘放到目的地,即可。我调用我的drop函数,它不断增加光盘的yCurrent,直到它达到yCan的递归和after()方法:
def drop(disc):
global yCan, yCurrent
can.move(disc, 0, 1)
yCurrent += 1
if yCurrent < yCan:
can.after(5, drop(disc))
现在我的问题是光盘的中间位置不显示,它只会在几秒后直接显示在底部。 经过一些研究后,我添加了一行来更新画布:
def drop(disc):
global yCan, yCurrent
can.move(disc, 0, 1)
yCurrent += 1
can.update()
if yCurrent < yCan:
can.after(5, drop(disc))
现在我看到我的光盘掉落了,但每次播放后都会变得迟钝;光盘只在我点击后几秒钟开始下降(触发它们摔倒)。另一个问题是,如果我通过非常快速的双击触发两个光盘几乎是相同的,那么第一个光盘会在中途停止下降,然后只是从画布上掉下来。
我的问题是,如何显示光盘的每一步&#39;没有can.update()
?
另外我将每个光盘id存储在一个列表(discList)中,是否有更方便的方式来存储动态创建的画布图像?
答案 0 :(得分:0)
在tkinter中执行动画的正确方法是使用一个执行一帧动画的函数,然后让它自己重复调用直到一些终端条件。
例如:
def move_object(obj_id):
can.move(obj_id, 0, 1)
x0,y0,x1,y1 = can.coords(obj_id)
if y0 < yCan:
can.after(5, move_obj, obj_id)
与您所写内容的主要区别在于您错误地使用了after
。你是这样做的:
can.after(5, drop(disc))
......这与此完全相同:
result = drop(disc)
can.after(5, drop)
注意区别?与command
属性一样,您必须为函数提供引用。然而,您调用函数,然后将结果提供给after
。
这是一个非常简单的实验示例:
import tkinter as tk
root = tk.Tk()
canvas = tk.Canvas(root, width=200, height=200)
canvas.pack(fill="both", expand=True)
ball = canvas.create_oval(50,0,100,50, fill="red")
def animate(obj_id):
canvas.move(obj_id, 0, 3)
x0,y0,x1,y1 = canvas.coords(obj_id)
if y0 > canvas.winfo_height():
canvas.coords(obj_id, 50,-50, 100, 0)
canvas.after(50, animate, obj_id)
animate(ball)
root.mainloop()