javascript拼接导致画布滞后

时间:2014-10-13 13:12:02

标签: javascript canvas

我有一个简单的跑步游戏,平台从右向左滚动。这些平台存储在一个数组中,当它们不在屏幕上时,我使用array.splice(index,1)将其删除。然而,这会导致在确切的第二个拼接上产生如此轻微的滞后。我也使用了Array.shift(),但我仍然可以看到帧速率的略微下降,因为这被称为。有没有更好的方法来删除/破坏某些东西?

for(var x = 0; x < platforms.length; x++){
    var platform = platforms[x];

    platform.x -= 10;

    if(platform.x + platform.width < 0){
        platforms.shift();
    }
}

2 个答案:

答案 0 :(得分:2)

您可以不删除数组中的项目。

使用固定大小的数组(足够大以存储您需要的所有项目)并标记为已取消您不想再渲染的项目,您可以稍后重复使用这些标记的插槽。

或者,如果问题的域允许,您可以直接覆盖元素。

[编辑]

回应评论时需要考虑更多因素:

额外标志的评估是在时间上稳定的计算,这意味着您可以预见他们需要多长时间并查看它们是否适合以特定帧速率渲染的帧。另一方面,Array.splice可以触发垃圾收集,并且可能比其他语言控制流结构某个数量级更长。

垃圾收集是一项繁重的任务,应该在游戏的主循环中不惜一切代价避免垃圾收集,以实现流畅的帧速率。这里有一些资源和其他问题详细阐述了这一点,例如:http://buildnewgames.com/garbage-collector-friendly-code/

答案 1 :(得分:1)

转移和拼接是&#34;慢&#34;功能。他们可能会重建你的整个阵列。

想象一下拥有1000个物品的区域。转移可能会创建一个包含所有项目的新数组,但第一个项目除外。如果前100个项目现在导致移位,则重建100个阵列,包含900-1000个项目,这将导致大约100.000个插入,100个新阵列分配。

for(var i = 0; i < array.length; i++)
{
    if (array[i] == ....)
    {
        var newArray = new Array(array.length - 1);
        for(var o = 1; o < array.length; o++)
            newArray[o - 1] = array[o];
        array = newArray
    }
}

最糟糕的情况,长度为1000,这将导致:

for ( i = 0 to 1000 )
    for ( o = i to 1000 )
        recreate the array

这将是0.5百万次迭代和数组的重新创建。虽然这可以通过1次迭代(动态大小的数组)或2次传递(固定大小的数组)来修复:

// dynamic size
var newArray = new Array();
for(var i = 0; i < array.length; i++)
{
    if (array[i] != ....)
        newArray.push(array[i]);
}
array = newArray;

// fixed size 
var cnt = 0;
for(var i = 0; i < array.length; i++)
    if (array[i] != ....)
        cnt++;
var newArray = new Array(cnt);
for(var i = 0, o = 0; i < array.length; i++)
    if (array[i] != ....)
        newArray[o++] = array[i];
array = newArray;

和for循环的另一个简单优化(如果在for循环中修改数组,这显然不会起作用):

for(var i = 0, l = array.length; i < l; i++)

(是的,我知道有些数字可能会关闭。但它可以解决问题。)