2017-04-20 72 views
1

伙计们。我正在尝试创建我自己的纸牌游戏版本。尝试将我的卡片移至画布中心点击事件时出现以下问题。这里是我的代码Tkinter - 如何从慢动作画布移动图像

import tkinter as tk 

class gui(tk.Frame): 

def __init__(self, parent, *args, **kwargs): 
    tk.Frame.__init__(self, parent, *args, **kwargs) 
    self.canvas = tk.Canvas(parent, bg="blue", highlightthickness=0) 
    self.canvas.pack(fill="both", expand=True) 
    self.img = PhotoImage(file="card.gif") 
    self.card = self.canvas.create_image(10, 10, image=self.img) 
    self.canvas.tag_bind(self.card, '<Button-1>', self.onObjectClick1) 

def onObjectClick1(self, event): 
    if self.canvas.find_withtag("current"): 
     x = 400 
     y = 400 
     self.canvas.coords("current", x, y) 
     self.canvas.tag_raise("current") 

if __name__ == "__main__": 
root = tk.Tk() 
w, h = root.winfo_screenwidth(), root.winfo_screenheight() 
root.geometry("%dx%d+0+0" % (w, h)) 
gui(root) 
root.mainloop() 

我想要的是将我的卡,但不只是移动从一个坐标到另一个,但慢动作效果给它一个例子。

回答

1

其基本思想是编写一个函数来移动一个小对象,然后安排自己在短暂的延迟后再次被调用。它会这样做直到它到达目的地。

这是一个非常简单的例子,它可以独立移动几个项目。您可以通过更改speed参数或更改delta_xdelta_y的值来调整速度。

这是一个非常简单的算法,它只是将x和y坐标增加一个固定量。您可以改为沿着曲线或直线计算等距点。无论如何,动画技术保持不变。

import Tkinter as tk 

def move_object(canvas, object_id, destination, speed=50): 
    dest_x, dest_y = destination 
    coords = canvas.coords(object_id) 
    current_x = coords[0] 
    current_y = coords[1] 

    new_x, new_y = current_x, current_y 
    delta_x = delta_y = 0 
    if current_x < dest_x: 
     delta_x = 1 
    elif current_x > dest_x: 
     delta_x = -1 

    if current_y < dest_y: 
     delta_y = 1 
    elif current_y > dest_y: 
     delta_y = -1 

    if (delta_x, delta_y) != (0, 0): 
     canvas.move(object_id, delta_x, delta_y) 

    if (new_x, new_y) != (dest_x, dest_y): 
     canvas.after(speed, move_object, canvas, object_id, destination, speed) 

root = tk.Tk() 
canvas = tk.Canvas(root, width=400, height=400) 
canvas.pack() 

item1 = canvas.create_rectangle(10, 10, 30, 30, fill="red") 
item2 = canvas.create_rectangle(360, 10, 380, 30, fill="green") 

move_object(canvas, item1, (200, 180), 25) 
move_object(canvas, item2, (200, 220), 50) 

root.mainloop() 
1

为了“动画”移动您的卡片,需要一个系统来分解要移动的总距离,然后在一段时间内移动/更新较小的距离。

例如,如果你想移动卡400台X & Y,这样的事情可能工作:

total_time = 500 #Time in milliseconds 
period = 8 
dx = 400/period 
dy = 400/period 

for i in range(period): 
    self.canvas.move(chosen_card, dx, dy) 
    root.after(total_time/period) #Pause for time, creating animation effect 
    root.update() #Update position of card on canvas 

这可能是一个动画一个基本前提。当然,您需要编辑我的示例中的total_timeperiod变量以创建您认为正确的变量。

+0

'root.after(TOTAL_TIME /期)'有效地把该应用程序睡觉。这不会产生良好的用户体验。 –

0

这下面的代码(准备复制/粘贴和运行,因为它是)给我的盒子一个很好的平滑运动:

import tkinter as tk 
import time 

class gui(tk.Frame): 

    def __init__(self, parent, *args, **kwargs): 
     tk.Frame.__init__(self, parent, *args, **kwargs) 
     self.canvas = tk.Canvas(parent, bg="blue", highlightthickness=0) 
     self.canvas.pack(fill="both", expand=True) 
     self.img = tk.PhotoImage(file="card.gif") 
     self.card = self.canvas.create_image(10, 10, image=self.img) 
     self.canvas.tag_bind(self.card, '<Button-1>', self.onObjectClick1) 

    def onObjectClick1(self, event): 
     if self.canvas.find_withtag("current"): 
      x = 400 
      y = 400 
      self.canvas.coords("current", x, y) 
      self.canvas.tag_raise("current") 
      total_time = 500 #Time in milliseconds 
     period = 400 
     dx = 400/period 
     dy = 400/period 
     for i in range(period): 
      self.canvas.move(self.card, dx, dy) # chosen_card 
      time.sleep(0.01) 
      # root.after(total_time/period) #Pause for time, creating animation effect 
      root.update() #Update position of card on canvas 

if __name__ == "__main__": 
    root = tk.Tk() 
    w, h = root.winfo_screenwidth(), root.winfo_screenheight() 
    root.geometry("%dx%d+0+0" % (w, h)) 
    gui(root) 
    root.mainloop()