基于 WebGL 的 3D 呈现 A* Search Algorithm

494 阅读1分钟

实现代码比较容易一百多行,不过算法核心在astar.js了,界面核心在ht.js里面了,我只需要构建网格信息,只需监听用户点击,然后调用astar.js进行最短路径计算,将结果通过动画的方式呈现出走动的过程,所有代码如下:

function init() {                
    w = 40; m = 20; d = w * m / 2;            
    gridRows = [];                        
    dm = new ht.DataModel();             
    g3d = new ht.graph3d.Graph3dView(dm);                
    g3d.setGridVisible(true);
    g3d.setGridColor('#BBBBBB');
    g3d.setGridSize(m);
    g3d.setGridGap(w);            
    g3d.addToDOM();                                                                                                        
    g3d.sm().setSelectionMode('none');            
    anim = startBall = endBall = null;                        
    g3d.getView().addEventListener(ht.Default.isTouchable ? 'touchstart' : 'mousedown', function(e){                
        if(!anim){
            var p = g3d.getHitPosition(e);
            var x = Math.floor((p[0] + d)/ w);
            var y = Math.floor((p[2] + d)/ w);
            var endBall = dm.getDataByTag("cell_" + x + "_" + y);
            if(endBall && endBall.s('batch') !== 'wall'){                      
                if(startBall.a('x') === x && startBall.a('y') === y){
                    return;
                }                        
                var g = new Graph(gridRows, { 
                    diagonal: formPane.v('diagonal') 
                });
                var start = g.grid[startBall.a('x')][startBall.a('y')];
                var end = g.grid[ x][y];
                var result = astar.search(g, start, end, {
                    closest: formPane.v('closest')                            
                });  
                if(!result.length){
                    return;
                }
                x = result[result.length-1].x;
                y = result[result.length-1].y;
                endBall = dm.getDataByTag("cell_" + x + "_" + y);
                endBall.s('3d.visible', true);
                startBall.s('3d.visible', false);
                formPane.setDisabled(true);
                anim = ht.Default.startAnim({
                    duration: 700,
                    finishFunc: function(){  
                        for(var i=0; i