【问题标题】:how to make objects move smoothly tkinter如何使对象平滑移动tkinter
【发布时间】:2018-05-20 02:24:34
【问题描述】:

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

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

【问题讨论】:

  • 您需要在 su=ystem 上调整按键重复的延迟时间
  • 附带说明,这不是类的用途。你想创建一个实例,然后用那个实例做事,而不是用类本身。通常,实例会存储一些状态,方法会在self 上使用该状态。也许像this

标签: python tkinter


【解决方案1】:

您可以使用多个布尔值(上、右、左、下)来表示坦克是否正在前进。当一个键被按下时,将布尔值设置为 true,当它被释放时,将布尔值设置为 false。使用带有import threading 的单独线程/while 循环制作游戏循环,并在游戏循环中检查其中一个布尔值是否为真。例如,如果代表右的布尔值为真,则程序将添加到坦克的 x 坐标。

【讨论】:

    【解决方案2】:

    您的问题的第一部分是捕获KeyPress and KeyRelease events 而不是关键事件。

    但是事情变得复杂了。你希望坦克每 120 毫秒移动一次,而不是尽可能快,对吧?所以,你唯一能做的就是设置一个 after 回调,这样你就可以每 120 毫秒运行一次代码,并且让关键事件设置一些标志,告诉你如何移动坦克(或不移动它)关于被按下的内容。

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

    仍然可行,但并不容易。而且它并不完美 - 快速按键可以欺骗您提出的任何去抖动算法,并且快速按键是您经常希望在游戏中允许的。

    更好的解决方案可能是使用完全不同的库重新开始,例如 PyGame Zero,而不是 Tkinter。为游戏设计的库将具有帧循环,因此您无需使用 after 并检查一堆标志,将捕获“原始”键盘事件,以便您可以立即响应它们等等。当您走得更远并且想要,例如,为你的坦克使用精灵,你也不必像 Tkinter 那样重新发明那些轮子。

    【讨论】:

      猜你喜欢
      • 2011-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多