ฉันจะเคลื่อนไหวอย่างราบรื่นของรายการ Canvas ใน Tkinter ได้อย่างไร

ฉันกำลังพยายามเล่นกับเหตุการณ์ที่ขับเคลื่อนด้วยแป้นพิมพ์ใน Tkinter เพื่อที่ฉันจะได้ย้ายวัตถุไปรอบๆ วิดเจ็ต Canvas ขึ้น ลง ซ้ายและขวาใช้งานได้ดี แต่เมื่อฉันพยายามตั้งโปรแกรมสองปุ่มพร้อมกัน การเคลื่อนไหวนั้นไม่ใช่การเคลื่อนไหวในแนวทแยงที่ราบรื่น นอกจากนี้ เมื่อใดก็ตามที่มีการกดปุ่ม วัตถุจะเคลื่อนที่ จากนั้นจะมีความล่าช้าเล็กน้อย จากนั้นจึงเคลื่อนที่อย่างราบรื่น ฉันจะทำให้การเคลื่อนไหวราบรื่นได้อย่างไร เมื่อกดปุ่มเพียงชั่วครู่ และฉันจะเคลื่อนไหวในแนวทแยงได้อย่างราบรื่นได้อย่างไร

นี่คือรหัสจนถึงตอนนี้:

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()

ขอบคุณมาก!

แก้ไข:

ขอบคุณสำหรับข้อเสนอแนะทั้งหมดของคุณ ฉันพยายามใช้แอนิเมชั่นวนซ้ำเพื่อแก้ไขความล่าช้าเล็กน้อยหลังจากกดปุ่มลูกศร แต่ตอนนี้ฉันค้างอยู่ รหัสใหม่ของฉันแสดงอยู่ด้านล่าง แต่การรันโปรแกรมไม่ส่งผลให้รายการแคนวาสเคลื่อนไหว ประการแรก แนวคิดสำหรับการวนซ้ำแอนิเมชั่นถูกต้องหรือไม่ และประการที่สอง ฉันจะเรียกใช้ฟังก์ชัน 'ย้าย' เพื่อให้รายการเคลื่อนไหวได้ที่ไหน กรุณาช่วย - ขอบคุณ!

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 แหล่งที่มา
comment
สร้างตัวแปร velocity_x และ velocity_y ซึ่งจะกำหนดว่าแต่ละเฟรมควรเคลื่อนไปไกลแค่ไหน เหตุการณ์การกดคีย์และคีย์อัพควรปรับเปลี่ยนความเร็ว ไม่ใช่ตำแหน่ง อย่างไรก็ตาม event.keysym == 'Down' and 'Right' ไม่ได้ทำในสิ่งที่คุณคิดว่ากำลังทำอยู่ a == b and c เทียบเท่ากับ (a == b) and c ไม่ใช่ a == (b and c) หรือ a == (b + c)   -  person Kevin    schedule 30.09.2014
comment
ความล่าช้าระหว่างการดำเนินการครั้งแรกและการเคลื่อนไหวที่ราบรื่นอาจเป็นปัญหาเกี่ยวกับไดรเวอร์แป้นพิมพ์ เมื่อคุณกดปุ่ม คนขับจะรอสักครู่ก่อนที่จะทำให้เหตุการณ์สำคัญที่เกี่ยวข้องกับกุญแจนั้นท่วมท้น พารามิเตอร์นี้เรียกว่า Repeat Delay บน Windows และ Keyboard Delay บน Linux คุณสามารถลองแก้ไขค่านี้ได้ แต่อาจขัดขวางการใช้งานแป้นพิมพ์สำหรับแอปพลิเคชันอื่นๆ วิธีแก้ปัญหาตามปกติคือการทริกเกอร์ตัวจับเวลาแบบวนซ้ำบน KeyPress และหยุดบน KeyRelease   -  person FabienAndre    schedule 30.09.2014
comment
ขอบคุณเพื่อน. เควิน เตะตัวเองเกี่ยวกับข้อผิดพลาดของเด็กนักเรียนเกี่ยวกับการใช้ AND! ฉันเป็นคนงี่เง่า ในแง่ของความเร็วไม่ใช่ตำแหน่ง คุณช่วยเพิ่มตัวอย่างเพื่อแสดงความหมายของคุณได้ไหม เพราะค่า 5 และ -5 ไม่ใช่ค่าที่ทำหน้าที่เป็นความเร็วอยู่แล้ว การเพิ่มหรือลดค่าเหล่านี้จะเปลี่ยนความเร็วของวัตถุ ขออภัยหากผมหนาแน่น ขอบคุณ FabienAndre เช่นกัน ชื่นชมมัน   -  person sw123456    schedule 30.09.2014
comment
FabienAndre ฉันหน้าด้านที่นี่ แต่คุณช่วยยกตัวอย่างเรื่องเวลาที่วนซ้ำได้ไหม ตรรกะสมเหตุสมผลดี แต่มีปัญหาในการนำไปใช้อย่างถูกต้อง ฉันได้เพิ่ม while loop บนสื่อซึ่งจะหยุดเมื่อปล่อย แต่โปรแกรมของฉันยังคงล็อคอยู่ ขออภัยและขอขอบคุณล่วงหน้า   -  person sw123456    schedule 30.09.2014
comment
โปรดไม่มีการวนซ้ำในขณะที่ไม่มีที่สิ้นสุด คุณไม่สามารถรับเหตุการณ์ใหม่ได้จนกว่าคุณจะออกจากตัวจัดการเหตุการณ์ ดังนั้นเหตุการณ์นั้นจะไม่กลับมาอีก   -  person user3757614    schedule 01.10.2014


คำตอบ (1)


การผูกเข้ากับคีย์พื้นฐานเป็นวิธีที่ผิดในการดำเนินการนี้ ให้ผูกเข้ากับคีย์ลงและปล่อยคีย์แทน และใช้สิ่งนั้นเพื่อสร้างพจนานุกรมของคีย์ที่กด ทุกๆ N ms ให้รันฟังก์ชันที่ใช้พจนานุกรมนั้นเพื่อกำหนดวิธีย้ายวัตถุ (ฉันไม่แน่ใจว่าตัวจับเวลา Tkinter มีคุณภาพที่จำเป็นในการดำเนินการนี้ถูกต้องหรือไม่)

อย่าลืมล้างพจนานุกรมหากโปรแกรมขาดโฟกัส

person user3757614    schedule 30.09.2014