Bagaimana saya bisa mencapai pergerakan item kanvas yang HALUS di Tkinter?

Saya mencoba bermain-main dengan acara yang digerakkan oleh keyboard di Tkinter sehingga saya bisa memindahkan objek di sekitar widget kanvas. Atas, Bawah, Kiri dan Kanan berfungsi dengan baik tetapi ketika saya mencoba memprogram dua tombol secara bersamaan, gerakannya bukanlah gerakan diagonal yang mulus. Selanjutnya, setiap kali tombol ditekan, benda akan bergerak, kemudian terjadi sedikit penundaan, dan kemudian bergerak dengan mulus. Bagaimana saya dapat mencapai gerakan mulus SAAT sebuah tombol ditekan dan bagaimana saya dapat mencapai gerakan diagonal yang mulus?

Ini adalah kode sejauh ini:

from tkinter import *

x = 10
y = 10
a = 100
b = 100

def change_coord(event):
        if event.keysym == 'Up':
            canvas1.move(rect, 0,-5)
        if event.keysym == 'Up' and 'Right':
            canvas1.move(rect, 5,-5)
        if event.keysym == 'Up' and 'Left':
            canvas1.move(rect, -5,-5)
        if event.keysym == 'Down':
            canvas1.move(rect, 0,5)
        if event.keysym == 'Down' and 'Right':
            canvas1.move(rect, 5,5)
        if event.keysym == 'Down' and 'Left':
            canvas1.move(rect, -5,5)
        if event.keysym == 'Right':
            canvas1.move(rect, 5,0)
        if event.keysym == 'Left':
            canvas1.move(rect, -5,0)

window = Tk()
window.geometry("400x200")

#canvas and drawing
canvas1=Canvas(window, height = 200, width = 400)
canvas1.grid(row=0, column=0, sticky=W)
coord = [x, y, a, b]
rect = canvas1.create_rectangle(*coord, outline="#fb0", fill="#fb0")

#capturing keyboard inputs and assigning to function
window.bind_all('<Up>', change_coord)
window.bind_all('<Down>', change_coord)
window.bind_all('<Left>', change_coord)
window.bind_all('<Right>', change_coord)
window.mainloop()

Terimakasih banyak!

EDIT:

Terima kasih atas semua saran Anda. Saya telah mencoba menerapkan loop animasi untuk mengatasi sedikit penundaan setelah menekan tombol panah tetapi sekarang saya buntu. Kode BARU saya ditampilkan di bawah tetapi menjalankan program tidak menyebabkan item kanvas berpindah. Pertama, apakah ide untuk loop animasi benar dan kedua di mana saya memanggil fungsi 'pindah' ​​untuk membuat item bergerak. Tolong bantu - terima kasih!

from tkinter import *

x = 10
y = 10
a = 100
b = 100
direction = None

def move():
    global x_vel
    global y_vel
    global direction
    if direction is not None:
        canvas1.move(rect, x_vel,y_vel)
        after(33,move)

def on_keypress(event):
    global direction
    global x_vel
    global y_vel
    if event.keysym == "Left":
        direction == "left"
        x_vel = -5
        y_vel = 0
    if event.keysym == "Right":
        direction == "right"
        x_vel = 5
        y_vel = 0
    if event.keysym == "Down":
        direction == "down"
        x_vel = 0
        y_vel = 5
    if event.keysym == "Up":
        direction == "up"
        x_vel = 0
        y_vel = -5

def on_keyrelease(event):
    global direction
    direction = None


window = Tk()
window.geometry("400x200")

#canvas and drawing
canvas1=Canvas(window, height = 200, width = 400)
canvas1.grid(row=0, column=0, sticky=W)
coord = [x, y, a, b]
rect = canvas1.create_rectangle(*coord, outline="#fb0", fill="#fb0")

#capturing keyboard inputs and assigning to function
window.bind_all('<KeyPress>', on_keypress)
window.bind_all('<KeyRelease>', on_keyrelease)
window.mainloop()

person sw123456    schedule 30.09.2014    source sumber
comment
Buat variabel velocity_x dan velocity_y, yang menentukan seberapa jauh persegi harus memindahkan setiap frame. Peristiwa keydown dan keyup harus mengubah kecepatan, bukan posisi. Ngomong-ngomong, event.keysym == 'Down' and 'Right' tidak melakukan apa yang Anda pikirkan; a == b and c setara dengan (a == b) and c, bukan a == (b and c) atau a == (b + c).   -  person Kevin    schedule 30.09.2014
comment
Penundaan antara tindakan pertama dan gerakan halus mungkin disebabkan oleh masalah yang terkait dengan driver keyboard. Saat Anda menekan sebuah tombol, pengemudi menunggu beberapa saat sebelum membanjiri peristiwa penting yang terkait dengan kunci tersebut. Parameter ini disebut Repeat Delay di windows dan Keyboard delay di Linux. Anda dapat mencoba mengubah nilai ini, namun hal ini dapat mengisyaratkan kegunaan keyboard untuk aplikasi lain. Solusi yang biasa dilakukan adalah dengan memicu pengatur waktu perulangan di KeyPress, dan menghentikannya di KeyRelease.   -  person FabienAndre    schedule 30.09.2014
comment
Terima kasih teman-teman. Kevin, menyalahkan diri sendiri tentang kesalahan anak sekolah saya terkait penggunaan AND! Saya seorang idiot. Mengenai kecepatan, bukan posisi, dapatkah Anda menambahkan contoh untuk menunjukkan maksud Anda karena bukankah nilai 5 dan -5 berperan sebagai kecepatan?, menambah atau mengurangi nilai ini akan mengubah kecepatan benda? Maaf jika saya padat. Terima kasih juga FabienAndre. Menghargai itu   -  person sw123456    schedule 30.09.2014
comment
FabienAndre, saya kurang ajar di sini, tetapi bisakah Anda memberikan contoh waktu perulangan, logika masuk akal tetapi kesulitan untuk menerapkannya dengan benar. Saya telah menambahkan loop sementara saat ditekan yang terputus saat dirilis tetapi program saya tetap terkunci. Mohon maaf dan terima kasih sebelumnya.   -  person sw123456    schedule 30.09.2014
comment
Tolong, tidak ada loop while yang tak terbatas. Anda tidak memiliki kemampuan untuk menerima event baru sampai Anda keluar dari event handler, jadi event tersebut tidak akan pernah kembali.   -  person user3757614    schedule 01.10.2014


Jawaban (1)


Mengikat kunci dasar adalah cara yang salah untuk melakukan ini. Sebagai gantinya, ikat ke tombol bawah dan pelepasan tombol, dan gunakan itu untuk membuat kamus tombol yang ditekan. Setiap N ms, jalankan fungsi yang menggunakan kamus tersebut untuk menentukan cara memindahkan objek. (Saya tidak yakin apakah pengatur waktu Tkinter memiliki kualitas yang diperlukan untuk melakukan hal ini dengan benar.)

Pastikan untuk menghapus kamus jika program kehilangan fokus.

person user3757614    schedule 30.09.2014