2017-04-20 10 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つは、スローモーション効果でそれを与えることなく、他の座標からだけで移動しないの例です。

答えて

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

あなたのカードを動かすためには、動かすべき総距離を分解し、ある期間に渡ってより小さい距離で移動/更新するシステムが有効です。

あなたはX & yの中のカードに400台を移動したい場合たとえば、このような何かが仕事ができる:

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() 
関連する問題