为了好玩,我试图在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帧。 我想知道三件事:
当你想在每一步画出100个矩形时,是否有可能用Tkinter画布写一条平滑,不滞后(20 fps)的蛇?
threading.Timer
是调用时间步长函数的正确选择吗?
为什么我的键盘输入似乎被延迟了?
答案 0 :(得分:1)
尝试使用内置canvas.after(funciton,interval)
代替threading.timer。
答案 1 :(得分:0)
如果您没有在每个帧之间使用canvas.delete(...),则会发生内存泄漏。
答案 2 :(得分:0)
是的,您可以在屏幕上创建一个包含许多对象的流畅运行游戏,并且您可以在没有线程的情况下执行此操作。但是,这取决于你如何定义&#34; smooth&#34;和&#34;很多&#34;,这取决于你如何实现它。
如果你有一个算法在每次迭代时删除并重新创建场景中的所有内容,它将运行得非常慢。执行动画的正确方法是创建一次要设置动画的对象,并且只创建一次。然后,对于每个帧,您可以使用画布方法itemconfigure
,move
和coords
重新配置或移动它们。
我已经看到这项工作在画布上有数百个项目。但是,如果你有数千人,它就开始陷入困境。此外,即使您删除旧项目,当您创建数千个项目时,画布也会出现已知的性能问题。
因此,与许多与性能相关的问题一样,它部分归结为最终算法。例如,在蛇形游戏中,您可以选择在每一帧上重绘整条蛇,或者您可以查看问题并意识到您只需移动蛇的一段或两段。第一种方法会很慢,第二种方法会非常快。
最重要的是,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个矩形的颜色,我的性能也很好,没有闪烁。