带有递归的Javascript动画,奇怪的行为

时间:2013-09-14 11:02:17

标签: javascript animation recursion

我试图在javascript中使用ruzzle解算器进行编码。现在它只是挖掘迷宫并找到所有可能的路径(将来我会将它们与字典相匹配,以找到真正有效的字词)

您可以在此处查看:http://178.239.177.105/ruzzle/

我想用动画来展示算法是如何工作的,但我发布了一个问题。 如果你加载它,页面就不会显示任何内容,并且我的浏览器会在一段时间后崩溃。

但是...

如果在递归函数中间的某个位置设置警报("")函数,您将能够完成算法中的任何步骤。 特别是如果您将浏览器设置为阻止显示任何进一步的警报消息,您最终会看到动画在迷宫上工作。

我实际上是通过setInterval()尝试这样做,但是无法正常工作。

所以我有两个问题: - 为什么脚本会导致页面崩溃,如果有警报则不会崩溃? - 如何在wait()机制上使用某种方式正确显示动画?

由于

您可以查看所有代码,方法是浏览页面并查看源代码,但为了清楚起见,我会在此处粘贴相关代码:

你也可以在这里使用代码http://jsfiddle.net/Gcw2U/ (你必须取消注释使其运行的最后一行)

        //this matrix of chars rapresent the 4x4 puzzle
          var ruzle_model = [["w","a","l","k"],["m","o","o","n"],["h","a","t","e"],["r","o","p","e"]];



        // ""offsets" rapresent the four motion vector(up,down,left,right)
        // used to visit the matrix
        var offsets = [[1,0],[0,1],[-1,0],[0,-1]];

//recursive function to dig the maze
            function path(m,i,j,paths,checkeds){
                alert("SET BROWSER TO AVOID NEXT ALERTS MSGs!");
                //base case, if not hitting a wall or already checked cell
                if ( ! (i<=3 && i>=0 && j>=0 && j<=3) || isChecked(checkeds,i,j)){
                    terminal.innerHTML = terminal.innerHTML + "-"+ paths;
                    uncheckAllCells();
                    return paths;
                    }

                //call path for every direction (up,down,left,right) stored in offsets
                var tmp = [];
                for (var c=0; c<offsets.length;++c){
                    var offset = offsets[c];
                    checkCells(i,j);
                    checkeds.push(new Array(i,j));
                    tmp.push(path(m,i+offset[0],j+offset[1],paths + m[i][j],copy(checkeds)));
                }

                return tmp;
            }


            //call path on every cell in the maze
            function ruzzle(r){
                var sol = []
                for(var i=0; i<4; ++i){
                    for(var j=0; j<4; ++j){
                        var checkeds = new Array();
                        sol.push(path(r,i,j,'',checkeds));
                    }
                }
                terminal.innerHTML = sol;
                return sol;
            }

1 个答案:

答案 0 :(得分:0)

Javascript循环和递归会禁止呈现页面,因此在脚本停止执行之前,所做的任何更改都将保持不可见,就像您生成alert一样。当用户设置“不显示警报消息”时,警报仍会产生执行时间到底层事件循环,这将更新页面。

对于尽可能快的(高fps)动画,请使用requestAnimationFrame()

在您的情况下,setTimeout()是最佳选择。在递归调用path

时设置超时
function recursive(args) {
    // do stuff to args
    setTimeout(function () {
        recursive(args);
    }, 5);
}

Example