马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
//调用工具类获取路线
let route = AStarSearch.getRoute(start_point, end_point, this.mapFloor.map_point);
map_point 是所有可走点的集合
- import { _decorator, Component, Node, Prefab, instantiate, v3, Vec2 } from 'cc';
- import { oops } from "../../../../../extensions/oops-plugin-framework/assets/core/Oops";
- import { GameWorld } from "../../../GameWorld";
- import { MapFloor, RowColData } from "../../../../Scripts/MapEditor/MapFloor";
- export class Point {
- x: number;
- y: number;
- constructor(x: number, y: number) {
- this.x = x;
- this.y = y;
- }
- G: number = 0; //G = 从起点A,沿着产生的路径,移动到网格上指定方格的移动耗费。
- H: number = 0; //H = 从网格上那个方格移动到终点B的预估移动耗费
- F: number = 0; //F = G + H
- father: Point = null; //这个点的上一个点,通过回溯可以找到起点
- is_close: boolean = false; //是否关闭搜索
- }
- export class AStarSearch {
- static start: Point = null; //起点
- static end: Point = null; //终点
- static map: Map<string, Point> = null; //地图point
- static openSet: Set<Point> = new Set(); //开放队列
- static pppp: Point = null; //执行完寻路,它就有值了,除非没找到
- /**
- * 获取路线 (此寻路不走斜线)
- */
- static getRoute(start: Point, end: Point, map_point: Map<string, { row: number, col: number }>): Point[] {
- //清空上次寻路,并赋值
- this.is_find = false;
- this.openSet.clear();
- this.pppp = null;
- this.start = { ...start };
- this.end = { ...end };
- this.map = new Map<string, Point>();
- map_point.forEach((value, key) => {
- let point = new Point(value.row, value.col);
- this.map.set(key, point);
- });
- let route = new Array<Point>();
- let keyStr = this.start.x + "_" + this.start.y;
- if (!this.map.has(keyStr)) {
- return route;
- }
- this.map.get(keyStr).G = 0; //起点的G是0
- //开始寻路
- try {
- this.search(this.start); //内存不够会报错,一般是起点或终点封闭
- } catch (error) {
- console.warn("位置不对", error);
- return route;
- }
- if (this.pppp) {
- this.getFather(this.pppp, route);
- }
- return route;
- }
- /**
- * 寻路
- */
- static is_find = false; //是否已经找到路线
- static search(point: Point) {
- if (point.x == this.end.x && point.y == this.end.y) {
- this.is_find = true;
- this.pppp = point;
- return;
- }
- let arr = this.getAround(point);
- arr.forEach(p => {
- this.setFather(p, point);
- });
- //arr按照F排序 从小到大
- this.openSet = new Set([...this.openSet].sort(this.compare));
- //递归继续找
- this.openSet.forEach((pp, index, arr) => {
- if (pp.is_close) { //删除没用的
- this.openSet.delete(pp);
- }
- if (!this.is_find) {
- this.search(pp);
- }
- });
- }
- /**
- * 获取周围4个点,上下左右
- */
- static getAround(point: Point) {
- point.is_close = true;
- let arr = new Array<Point>();
- let index: string;
- let p: Point;
- //上、下、左、右
- let aroundPos = [
- { x: point.x, y: point.y - 1 },
- { x: point.x, y: point.y + 1 },
- { x: point.x - 1, y: point.y },
- { x: point.x + 1, y: point.y }
- ]
- aroundPos.forEach(point => {
- index = point.x + "_" + point.y;
- p = this.map.get(index);
- if (p && !p.is_close) {
- arr.push(p);
- this.openSet.add(p);
- }
- })
- return arr;
- }
- /**
- * point换父亲,并重新计算G、H、F
- */
- static setFather(son: Point, father: Point) {
- if (!son.father || son.father.G > father.G) {
- son.father = father;
- son.G = son.father.G + 1;
- son.H = Math.abs(son.x - this.end.x) + Math.abs(son.y - this.end.y);
- son.F = son.G + son.H;
- }
- }
- /**
- * 比较器
- */
- static compare(p1: Point, p2: Point) {
- if (p1.F > p2.F) {
- return 1;
- } else {
- return -1;
- }
- }
- /**
- * 递归 把祖宗放进route里面
- */
- static getFather(point: Point, route: Array<Point>) {
- let father = point.father;
- if (father) {
- this.getFather(father, route);
- }
- route.push(point);
- }
- }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |