Ваш код имеет несколько проблем, например, функция animate()
будет работать непрерывно, даже если нет события нажатия клавиши.Также код может быть намного лучше, как вы можете использовать <KeyPress>
для ускорения и <KeyRelease>
для замедления.Я создал пример того, что вы пытаетесь сделать.

Я использовал after(1,..)
до ускорение и замедляется плавно, поскольку длительные нажатия клавиш имеют заметную задержку.
from tkinter import *
root = Tk()
root.geometry('1200x50+50+0')
speed = DoubleVar(value=1) # Speed of the item
multiplier = DoubleVar(value=0.05) # Increase / Decrease rate
acc_id = None # after id for acceleration
des_id = None # after id for deceleration
canvas = Canvas(root, bg='pink')
canvas.pack(expand=1, fill='both')
# Player item
player = canvas.create_rectangle(10,10,40,40, fill='grey', outline='black')
def direction(key):
"""Moves the item according to the arrow keys"""
if key == 'Left': canvas.move(player, -speed.get()*multiplier.get(), 0)
if key == 'Right': canvas.move(player, speed.get()*multiplier.get(), 0)
# if key == 'Up': canvas.move(player, 0, -speed.get()*multiplier.get())
# if key == 'Down': canvas.move(player, 0, speed.get()*multiplier.get())
def accelerate(evt=None):
"""Increase the speed."""
global des_id, acc_id
# set the values according to your needs
multiplier.set( multiplier.get() + 0.05 )
direction(evt.keysym)
if des_id: canvas.after_cancel(des_id)
acc_id = canvas.after(1, accelerate, evt)
def decelerate(evt=None):
"""Decrease the speed."""
global des_id, acc_id
if acc_id: canvas.after_cancel(acc_id)
# set the values according to your needs
multiplier.set( multiplier.get() - 0.05 )
if multiplier.get() >= 0:
direction(evt.keysym)
des_id = canvas.after(1, decelerate, evt)
root.bind('<KeyPress>', accelerate)
root.bind('<KeyRelease>', decelerate)
root.mainloop()