Javascript 2d Matrix迭代替代/优化?

时间:2012-08-12 14:50:30

标签: javascript arrays canvas matrix

所以我用javascript和canvas创建了一个沙子模拟。

我的第一种方法是array填充objects,其值xy。 每个物体代表一粒沙子。

这种方法适用于大型帆布,但在约600粒后开始减速。

我的下一个方法是二维矩阵,其中每个index都是01。 它在200 x 200画布上工作正常,但随着画布大小的增加,它变得太慢了。

..这是合理的,因为例如800 x 600画布的长度为480k

所以我的问题是,如何优化这样的事情?

如果您需要,可以使用以下代码:

var draw = function() {

    if (MOUSE_DOWN) { cast_grains(); }

    for (var i = matrix.length; i > 0; i--) {
        if (matrix[i] == "1") {

            var x = i % canvas.width;
            var y = Math.floor(i / canvas.width);

            bfr.fillStyle = "#000";
            bfr.fillRect(x, y, 1, 1);

            /* ... movement calculation ... */

            bfr.fillStyle = "rgb(255, 255, 200)";
            bfr.fillRect(x, y, 1, 1);
        }
    }

    ctx.drawImage(buffer, 0, 0);
};

2 个答案:

答案 0 :(得分:0)

您基本上需要使用不同的数据结构。我创建了类似的东西(an MMO version of Conway's Game of Life),它使用了一块大小为2 ^ 106的板子(如果我没弄错的话,它将近80万亿千万亿个单元)。

诀窍是只存储活细胞的坐标(以向量的形式)。由于活细胞的数量远远少于死细胞的数量,因此最终只占用很少的空间。

由于您将沙粒存储为坐标向量,因此您还可以不需要在循环中计算xy。你的功能看起来像:

var draw = function() {

    if (MOUSE_DOWN) { cast_grains(); }

    for (var i = grains.length - 1; i >= 0; i--) {
        var x = grains[i][0];
        var y = grains[i][1];

        bfr.fillStyle = "#000";
        bfr.fillRect(x, y, 1, 1);

        /* ... movement calculation ... */

        bfr.fillStyle = "rgb(255, 255, 200)";
        bfr.fillRect(x, y, 1, 1);
    }

    ctx.drawImage(buffer, 0, 0);
};

答案 1 :(得分:0)

首先,我会使用Chrome的开发者工具来分析您的应用,并找出究竟是什么的瓶颈。

如果碰撞检测算法随着对象数量的增加而减慢修复,则可以实现四叉树以减少比较次数。有关javascript实现,请参阅here