提问者:小点点

如何使物体平稳移动


当你按下按钮移动“坦克”时,它会启动,但随后会停止并再次启动。有没有办法让它不那么做?

from tkinter import *
from tkinter.constants import LEFT
root = Tk()
c = Canvas(root, width=400, height=400)
tank = c.create_rectangle(200,200,250, 250, outline = 'dark green', 
fill='dark green')
c.pack()

class Tank:
    def move_left(self):
        c.move(tank, -5, 0)
    def move_right(self):
        c.move(tank, 5,0)
    def move_up(self):
        c.move(tank, 0, -5) 
    def move_down(self):
        c.move(tank, 0, 5)           

c.bind('<Left>', Tank.move_left)
c.bind('<Right>', Tank.move_right)
c.bind('<Up>', Tank.move_up)
c.bind('<Down>', Tank.move_down)
c.focus_set()            
root.mainloop()     

共2个答案

匿名用户

您可以使用几个布尔值(上、右、左、下)表示坦克是否朝某个方向行驶。按下键时,将布尔值设置为true,释放键时,将布尔值设置为false。使用单独的线程/while循环和import threading创建一个游戏循环,并在游戏循环中检查其中一个布尔值是否为真。例如,如果表示右的布尔值为true,则程序将添加到油箱的x坐标。

匿名用户

问题的第一部分是捕获KeyPresskeyrease事件,而不是关键事件。

但是事情变得复杂了。你希望坦克每120毫秒移动一次,而不是尽可能快,对吗?因此,您唯一能做的就是在回调之后设置一个,这样您就可以每隔120毫秒运行一些代码,让按键事件设置一些标志,告诉您如何根据按下的内容移动水箱(或不移动水箱)。

这是可行的,但下一个问题更大: Tkinter在高级别捕获关键事件——在你的操作系统重新映射之后(所以你得到的是E,而不是shifte),其中包括自动重复。为了解决这个问题,你必须编写一些代码来手动进行“去重写”。

这仍然是可行的,但并不容易。快速按下按键并不完美,它可以愚弄你想出的任何去抖动算法,而快速按下按键是你在游戏中经常希望允许的。

一个更好的解决方案可能是从一个完全不同的库开始,比如PyGame Zero,而不是Tkinter。为游戏设计的库将有一个框架循环,所以你不需要在之后使用并检查一堆标志,将捕获“原始”键盘事件,这样你就可以立即响应它们,等等。当你走得更远,想要,例如,为你的坦克使用精灵时,你也不必像对待Tkinter那样重新发明那些轮子。