我正在用javascript画布编写游戏,有时会遇到延迟。我认为这是因为我在画布上画了很多东西。
例如,我的背景不是一成不变的,它是从右向左移动的,因此每次我都必须清除整个画布。我不仅要清除颜色,还要清除移动游戏循环每个周期的图像。
我认为这是一个昂贵的操作,并且我在考虑是否有一些方法可以使此操作更便宜,例如使用双缓冲来清除背景(不知道是否可以使用双缓冲来清除背景吗?)。
还是我应该在整个游戏中使用双重缓冲?
(我不这样认为,因为我已经阅读到浏览器已经为您做到了)
最佳答案
由于您有时会遇到延迟,而且这不是一个低帧速率的问题,因此,我宁愿将目光转向邪恶的垃圾收集器:只要触发,应用程序就会冻结长达几毫秒,您会得到丢帧。
要注意这一点,您可以使用Google分析工具,在“时间轴” /“内存”中/按“记录”按钮:您可以看到当所用内存突然下降时发生了GC。
使用此工具时要当心,它会降低应用程序的运行速度,并且会自行创建垃圾(!)...
另外,由于任何函数调用都会产生一些垃圾,因此您无法拥有完整的平面内存行。
下面我展示了一个在优化内存使用之前制作的简单游戏的示意图,
每秒最多有5个GC:
这是内存优化后的相同游戏的图表:每秒大约有1个GC。由于我上面提到的限制,实际上这是我们所能获得的最好的结果,并且游戏不会丢帧并且感觉响应更快。
避免产生垃圾
-切勿创建对象,数组或函数。
-切勿增大或减小数组大小。
-注意隐藏对象的创建:Function.bind或Array.splice是两个示例。
你也可以 :
-收集(回收)您的物品
-使用粒子引擎处理大量/寿命短的对象。
如果您感兴趣,我制作了一个池lib(here)和一个粒子引擎(here)。
但是也许要做的第一件事是寻找对象的创建位置,并只创建一次。由于js是单线程的,因此实际上您可以将静态对象用于很多事情而没有任何风险。
只是一个小爆炸:
function complicatedComputation(parameters) {
// ...
var x=parameters.x, y = parameters.y, ... ...
}
// you can call creating an object each time :
var res = complicatedComputation ( { x : this.x, y : this.y, ... ... } );
//... or for instance define once a parameter object :
complicatedComputation.parameters = { x :0, y:0, ... ... };
// then when you want to call :
var params = complicatedComputation.parameters;
params.x = this.x ; params.y = this.y; ... ...
var res = complicatedComputation(params);
它的缺点是保留了先前的调用参数,因此,如果不进行调用,就不会变得不确定
设置它们,但是使用先前的值,因此您可能必须更改功能。
但另一方面,如果您多次调用具有相似参数的函数,则会非常方便。
快乐的记忆狩猎!