2017-04-20 35 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()