我可以用Tkinter写一个流畅的蛇游戏吗?

时间:2016-04-16 20:18:38

标签: python tkinter tkinter-canvas

为了好玩,我试图在Python / Tkinter中实现经典的蛇游戏。感觉非常迟钝,我不太确定,我是否可以解决这个问题。我试着简要介绍一下这个程序:

我首先构建画布,然后为每个箭头键添加一个事件处理程序:

root = self.root = Tk()
canvas = Canvas(root, width = width, height = height)
canvas.pack()
canvas.bind("<Left>", on_left) # on_left is a very short function

我也有时间步的功能。它绘制图形并将安排自己再次调用。该函数效率不高,因为它每次都重绘100个矩形:

def timestep(self):
    # draw the graphics here (about 100 filled rectangles)
    timer = threading.Timer(interval, timestep)
    timer.start()

现在,我有两个问题:

  • 即使我在interval中选择timestep()大约0.05(相当于每秒20帧),我也不会超过每秒3-5帧。
  • 似乎键盘的控制输入延迟了大约0.5秒。

我想知道三件事:

  • 当你想在每一步画出100个矩形时,是否有可能用Tkinter画布写一条平滑,不滞后(20 fps)的蛇?

  • threading.Timer是调用时间步长函数的正确选择吗?

  • 为什么我的键盘输入似乎被延迟了?

4 个答案:

答案 0 :(得分:1)

尝试使用内置canvas.after(funciton,interval)代替threading.timer。

答案 1 :(得分:0)

如果您没有在每个帧之间使用canvas.delete(...),则会发生内存泄漏。

答案 2 :(得分:0)

是的,您可以在屏幕上创建一个包含许多对象的流畅运行游戏,并且您可以在没有线程的情况下执行此操作。但是,这取决于你如何定义&#34; smooth&#34;和&#34;很多&#34;,这取决于你如何实现它。

如果你有一个算法在每次迭代时删除并重新创建场景中的所有内容,它将运行得非常慢。执行动画的正确方法是创建一次要设置动画的对象,并且只创建一次。然后,对于每个帧,您可以使用画布方法itemconfiguremovecoords重新配置或移动它们。

我已经看到这项工作在画布上有数百个项目。但是,如果你有数千人,它就开始陷入困境。此外,即使您删除旧项目,当您创建数千个项目时,画布也会出现已知的性能问题。

因此,与许多与性能相关的问题一样,它部分归结为最终算法。例如,在蛇形游戏中,您可以选择在每一帧上重绘整条蛇,或者您可以查看问题并意识到您只需移动蛇的一段或两段。第一种方法会很慢,第二种方法会非常快。

最重要的是,tkinter画布功能强大,可以在使用适当的算法实现时,一次平滑地动画几十个项目。

答案 3 :(得分:-1)

现有的答案并没有完全描述我如何才能最终解决问题,所以我将在这里回答我自己的问题:

主要问题是像function Vertex(coords, colors) { this.coords = coords; this.colors = colors; } var oneVertex = new Vertex([20.0, 20.0, 0.0, 1.0], [0.0, 0.0, 0.0, 1.0]); 这样的函数实际上会在每次调用时添加一个新的矩形。所以你会遇到性能问题,因为即使在很短的时间内你也会有太多的矩形。

您可以使用canvas.create_rectangle(...)删除部分或全部矩形。如果删除所有现有的矩形并在每个时间步长中创建新的矩形,性能就可以了,但屏幕会闪烁。

最好的方法是在初始化时创建一次矩形,然后在每个时间步长中更改它们的颜色:

canvas.delete(...)

即使我仍然每秒20次更改100个矩形的颜色,我的性能也很好,没有闪烁。