一个基于Phaser.TilemapLayer的寻路函数

最近写的一个寻路函数,算法比较简单,但并非A*算法。 因为要用到TilemapLayer的layer.data,所以把它挂在TilemapLayer上了。 旨在分享,相互学习,写的不好,欢迎指正,希望能抛砖引玉,对大家有所启发。 OK,上菜:

// *****************************
// Phaser.TilemapLayer.findTilePath 
// 基于TilemapLayer的寻路函数,寻找两个Tile之间的路径
// *****************************
// 参数:
// x0 : 起点Tile的x
// y0 : 起点Tile的y
// x1 : 终点Tile的x
// y1 : 终点Tile的y
// collideIndexes : 检测碰撞的index数组(像tilemap中的collideIndexes)
// 返回 : Tile数组或 false
// 数组第一个元素为终点Tile,依次到起点Tile,但最后不包含起点Tile
// 走路时,可用Array.pop()读取下一步的Tile
Phaser.TilemapLayer.prototype.findTilePath = function (x0, y0, x1, y1, collideIndexes, limit) {
    if(limit === undefined){ limit = 100; }
    var _layer = this.layer;
    var path = [];
    var excepts = []; 
    var roundTilesAll = [];
    var isFound = false;
    if(_layer.data[y1] === undefined || _layer.data[y1][x1] === undefined){ // 目标不存在?
        return false;
    }
    var curTile = _layer.data[y0][x0];
    var tarTile = _layer.data[y1][x1];
    if(collideIndexes.indexOf(tarTile.index) > -1){ // 目标不可及?
        return false;
    }
    roundTilesAll.push([curTile]);
    excepts.push(curTile);
    var step = 0;
    var rounds = this._getRoundTiles(roundTilesAll[0], excepts, collideIndexes);
    while(rounds.length > 0){
        step ++;
        if(step > limit){
            break;
        }
        if(rounds.indexOf(tarTile) > -1){
            isFound = true;
            break;
        }
        excepts = roundTilesAll[roundTilesAll.length - 1].concat();
        roundTilesAll.push(rounds);
        rounds = this._getRoundTiles(rounds, excepts, collideIndexes);
    }
    if(isFound){
        path.push(tarTile);
        var tmpTile;
        while(roundTilesAll.length > 1){
            rounds = roundTilesAll.pop();
            if(tarTile.x > 0){
                tmpTile = _layer.data[tarTile.y][tarTile.x - 1];
                if(rounds.indexOf(tmpTile) != -1){
                    path.push(tmpTile);
                    tarTile = tmpTile;
                    continue;
                }
            }
            if(tarTile.x < _layer.width-1){
                tmpTile = _layer.data[tarTile.y][tarTile.x + 1];
                if(rounds.indexOf(tmpTile) != -1){
                    path.push(tmpTile);
                    tarTile = tmpTile;
                    continue;
                }
            }
            if(tarTile.y > 0){
                tmpTile = _layer.data[tarTile.y - 1][tarTile.x];
                if(rounds.indexOf(tmpTile) != -1){
                    path.push(tmpTile);
                    tarTile = tmpTile;
                    continue;
                }
            }
            if(tarTile.y < _layer.height - 1){
                tmpTile = _layer.data[tarTile.y + 1][tarTile.x];
                if(rounds.indexOf(tmpTile) != -1){
                    path.push(tmpTile);
                    tarTile = tmpTile;
                    continue;
                }
            }
        }
        return path;
    }else{  
        return false;
    }
};
// *****************************
// _getRoundTiles (获取外围的Tiles)
// *****************************
// 返回 Array<Tile>
Phaser.TilemapLayer.prototype._getRoundTiles = function(roundTiles, exceptTiles, collideIndexes){
    var _layer = this.layer;
    var newRoundArray = [];
    var x;
    var y;
    var tmpTile;
    for (var i = 0; i < roundTiles.length; i++){
        x = roundTiles[i].x;
        y = roundTiles[i].y;
        if(x > 0){
            tmpTile = _layer.data[y][x - 1];
            if(collideIndexes.indexOf(tmpTile.index) == -1 && exceptTiles.indexOf(tmpTile) == -1){
                newRoundArray.push(tmpTile);
                exceptTiles.push(tmpTile);
            }
        }
        if(x<_layer.width - 1){
            tmpTile = _layer.data[y][x + 1];
            if(collideIndexes.indexOf(tmpTile.index) == -1 && exceptTiles.indexOf(tmpTile) == -1){
                newRoundArray.push(tmpTile);
                exceptTiles.push(tmpTile);
            }
        }
        if(y>0){
            tmpTile = _layer.data[y - 1][x];
            if(collideIndexes.indexOf(tmpTile.index) == -1 && exceptTiles.indexOf(tmpTile) == -1){
                newRoundArray.push(tmpTile);
                exceptTiles.push(tmpTile);
            }
        }
        if(y<_layer.height - 1){
            tmpTile = _layer.data[y + 1][x];
            if(collideIndexes.indexOf(tmpTile.index) == -1 && exceptTiles.indexOf(tmpTile) == -1){
                newRoundArray.push(tmpTile);
                exceptTiles.push(tmpTile);
            }
        }
    }
    return newRoundArray;
};