求一个a*寻路的ts版

因为是个新手,但是又想实现寻路,于是找了好多a*寻路的例子,可是都是似懂非懂的,而且都是代码,没有参考的demo(我这么认为),想问问大佬们有没有比较简单适合新手的寻路例子,最好有demo,谢谢了

export class Grid {

private _startNode: Node;    //起点

private _endNode: Node;      //终点

private _nodes: Array<any>;  //Node数组

private _numCols: number;    //网格行列

private _numRows: number;

public arr = [];

public constructor(numCols: number, numRows: number) {

    this._numCols = numCols;

    this._numRows = numRows;

    this._nodes = [];

    for (let i: number = 0; i < numCols; i++) {

        this._nodes[i] = [];

        for (let j: number = 0; j < numRows; j++) {

            this._nodes[i][j] = new Node(i, j);

            this.arr[i*10 + j] = 0;

        }

    }

}

public getNode(x: number, y: number): Node {

    return this._nodes[x][y];

}

public setEndNode(x: number, y: number) {

    this._endNode = this._nodes[x][y];

}

public setStartNode(x: number, y: number) {

    this._startNode = this._nodes[x][y];

}

public setWalkable(x: number, y: number, value: boolean) {

    this._nodes[x][y].walkable = value;

    this.arr[x*10 + y] = value ? 1 : 0;

}

public get endNode() {

    return this._endNode;

}

public get numCols() {

    return this._numCols;

}

public get numRows() {

    return this._numRows;

}

public get startNode() {

    return this._startNode;

}

public get Nodes() {

    return this._nodes;

}

}

export class Node {

public x: number;    //列

public y: number;    //行

public f: number;    //代价 f = g+h

public g: number;    //起点到当前点代价

public h: number;    //当前点到终点估计代价

public walkable: boolean = true; //

public parent: Node;

public costMultiplier: number = 1.0;

public constructor(x: number, y: number) {

    this.x = x;

    this.y = y;

}

}

export class AStar {

private _open: Array<any>;               //待考察表

private _closed: Array<any>;             //已考察表

private _grid: Grid;               //网格

private _endNode: Node;                  //终点Node

private _startNode: Node;                //起点Node

private _path: Array<any>;               //保存路径

private _heuristic: Function;            //寻路算法

private _straightCost: number = 1.0;     //上下左右走的代价

private _diagCost: number = Math.SQRT2;  //斜着走的代价 

public constructor() {

    //this._heuristic = this.manhattan;  

    //this._heuristic = this.euclidian;

    this._heuristic = this.diagonal;

}

//寻路

public findPath(grid: Grid): boolean {

    this._grid = grid;

    this._open = [];

    this._closed = [];

    this._startNode = this._grid.startNode;

    this._endNode = this._grid.endNode;

    this._startNode.g = 0;

    this._startNode.h = this._heuristic(this._startNode);

    this._startNode.f = this._startNode.g + this._startNode.h;

    return this.search();

}

//查找路径

public search(): boolean {

    var node: Node = this._startNode;

    while (node != this._endNode) {

        var startX = Math.max(0, node.x - 1);

        var endX = Math.min(this._grid.numCols - 1, node.x + 1);

        var startY = Math.max(0, node.y - 1);

        var endY = Math.min(this._grid.numRows - 1, node.y + 1);

        for (var i = startX; i <= endX; i++) {

            for (var j = startY; j <= endY; j++) {

                //不让斜着走

                // if (i != node.x && j != node.y) {

                //     continue;

                // }

                var test: Node = this._grid.getNode(i, j);

                if (test == node ||

                    !test.walkable ||

                    !this._grid.getNode(node.x, test.y).walkable ||

                    !this._grid.getNode(test.x, node.y).walkable) {

                    continue;

                }

                var cost: number = this._straightCost;

                if (!((node.x == test.x) || (node.y == test.y))) {

                    cost = this._diagCost;

                }

                var g = node.g + cost * test.costMultiplier;

                var h = this._heuristic(test);

                var f = g + h;

                if (this.isOpen(test) || this.isClosed(test)) {

                    if (test.f > f) {

                        test.f = f;

                        test.g = g;

                        test.h = h;

                        test.parent = node;

                    }

                }

                else {

                    test.f = f;

                    test.g = g;

                    test.h = h;

                    test.parent = node;

                    this._open.push(test);

                }

            }

        }

        for (var o = 0; o < this._open.length; o++) {

        }

        this._closed.push(node);

        if (this._open.length == 0) {

            console.log("AStar >> no path found",this._grid.endNode);

            return false

        }

        let openLen = this._open.length;

        for (let m = 0; m < openLen; m++) {

            for (let n = m + 1; n < openLen; n++) {

                if (this._open[m].f > this._open[n].f) {

                    let temp = this._open[m];

                    this._open[m] = this._open[n];

                    this._open[n] = temp;

                }

            }

        }

        node = this._open.shift() as Node;

    }

    this.buildPath();

    return true;

}

//获取路径

private buildPath(): void {

    this._path = new Array();

    var node: Node = this._endNode;

    this._path.push(node);

    while (node != this._startNode) {

        node = node.parent;

        this._path.unshift(node);

    }

}

public get path() {

    return this._path;

}

//是否待检查

private isOpen(node: Node): boolean {

    for (var i = 0; i < this._open.length; i++) {

        if (this._open[i] == node) {

            return true;

        }

    }

    return false;

}

//是否已检查

private isClosed(node: Node): boolean {

    for (var i = 0; i < this._closed.length; i++) {

        if (this._closed[i] == node) {

            return true;

        }

    }

    return false;

}

//曼哈顿算法

private manhattan(node: Node) {

    return Math.abs(node.x - this._endNode.x) * this._straightCost + Math.abs(node.y + this._endNode.y) * this._straightCost;

}

private euclidian(node: Node) {

    var dx = node.x - this._endNode.x;

    var dy = node.y - this._endNode.y;

    return Math.sqrt(dx * dx + dy * dy) * this._straightCost;

}

private diagonal(node: Node) {

    var dx = Math.abs(node.x - this._endNode.x);

    var dy = Math.abs(node.y - this._endNode.y);

    var diag = Math.min(dx, dy);

    var straight = dx + dy;

    return this._diagCost * diag + this._straightCost * (straight - 2 * diag);

}

public get visited() {

    return this._closed.concat(this._open);

}

}

let map = [
0, 1, 0, 1, 0, 0, 0,
0, 1, 0, 0, 0, 1, 0,
0, 1, 0, 1, 0, 0, 0,
0, 0, 0, 1, 0, 0, 0
];

    let gaird = new Grid(7, 4);
    let astr = new AStar();
    for (let i = 0; i < map.length; i++) {
        let x = i % 7;
        let y = Math.floor(i / 7);
        //障碍
        gaird.setWalkable(x, y, map[i] != 1);
    }

     //设置起点
    gaird.setStartNode(0, 0);
    //设置终点
    gaird.setEndNode(5, 0);
    //寻找路径
    astr.findPath(gaird);
    let pArrs = astr.path;
    let pathPoint = ""
    pArrs.forEach((a) => pathPoint += `[${a.x},${a.y}]->`);
    cc.log(pathPoint);
   //打印  [0,0]->[0,1]->[0,2]->[0,3]->[1,3]->[2,3]->[2,2]->[2,1]->[3,1]->[4,1]->[4,0]->[5,0]
3赞

谢谢大佬,我来研究研究

https://www.cnblogs.com/gamedaybyday/p/7778995.html