寻路算法 Astar A星算法
来源:互联网 发布:linux 安装服务 编辑:程序博客网 时间:2024/05/10 20:22
<span style="white-space:pre"></span>
<span style="white-space:pre"></span>首先是创建一些变量<pre name="code" class="javascript">private static _instance: Astar; static get instance(): Astar { if(!this._instance) { this._instance = new Astar(); } return this._instance; } /** * 开放节点列表 * */ m_openList: Array<AstarPathStep>/* = new Array<AstarPathStep>()*/; /** * 关闭节点列表 * */ m_closeList: foxgame.HashMap = new foxgame.HashMap(); /** * 横向移动一格的评分 * */ public static COST_HORIZONTAL = 20; /** * 竖向移动一格的路劲评分 * */ public static COST_VERTICAL = 10; /** * 斜向移动一格的路劲评分 * */ public static COST_DIAGONAL = 12; public constructor() { } /** * 地图类对象 * */ public tileMap: foxgame.TiledMap;
<span style="white-space:pre"></span>/** * 寻路 开始寻路计算 * */ public findPath(startPos: egret.Point,endPos: egret.Point,tileMap: foxgame.TiledMap) { this.tileMap = tileMap;//地图 var isFind = false; var starTime = egret.getTimer();//开始寻路的时间 if(egret.Point.distance(startPos,endPos) < 0.5) { if(Global.logLevel > Global.logLevelInfo) { console.log("You're already there! :P"); } return null; } if(tileMap.isPass(endPos.x,endPos.y) != true) { if(Global.logLevel > Global.logLevelInfo) { console.log("blocf or beyond the range"); } return null; } if (!this.m_openList) this.m_openList = new Array<AstarPathStep>(); this.m_closeList.clear(); var endStep = new AstarPathStep(endPos); var startStep = new AstarPathStep(startPos); startStep.m_hScore = this.getHValue(startStep,endStep); this.insertAndSort(startStep); var curStep: AstarPathStep; do { var elapesTime = egret.getTimer() - starTime;// if(elapesTime > 600) {// isFind = false;// //寻路超时// break;// } curStep = this.m_openList.shift(); curStep.setInClose(true); curStep.setInOpen(false); this.m_closeList.put(curStep.m_tilePos.x + "_" + curStep.m_tilePos.y,true); if(curStep.isEqualByPos(endPos)) { isFind = true; break; } var arundNodes = this.getAroundsNode(curStep.m_tilePos); for(var i = 0;i < arundNodes.length;i++) { var onePos = arundNodes[i]; var nextStep = new AstarPathStep(onePos); var gValue = this.getGValue(curStep,nextStep); var hValue = this.getHValue(endStep,nextStep); if(nextStep.m_inOpen == true) { if(gValue < nextStep.m_gScore) { nextStep.m_gScore = gValue; nextStep.m_hScore = hValue; nextStep.m_parent = curStep; this.findAndSort(nextStep); } } else { nextStep.m_gScore = gValue; nextStep.m_hScore = hValue; nextStep.m_parent = curStep; this.insertAndSort(nextStep); } } } while(this.m_openList.length > 0); if(isFind) { var path = this.createPath(curStep); //this.m_openList = new Array<AstarPathStep>(); this.m_openList.length = 0; this.m_closeList.clear(); return path; } else { //this.m_openList = new Array<AstarPathStep>(); this.m_openList.length = 0; this.m_closeList.clear(); return null; } }
创建路径
<span style="white-space:pre"></span>public createPath(step: AstarPathStep) { var path: Array<egret.Point> = new Array<egret.Point>(); do{ if(step.m_parent != null){ var curPos: egret.Point = step.m_tilePos; path.unshift(curPos); } step = step.m_parent; } while(step != null) return path; }那么AstarPathStep又是什么呢
export class AstarPathStep{ m_tilePos: egret.Point; m_gScore: number = 0; m_hScore: number = 0; m_parent: AstarPathStep; m_inOpen = false; m_inClose = false; public constructor(tilePos: egret.Point) { this.m_tilePos = tilePos; this.m_parent = null; } /** * 返回这个点的f评分 * */ public fScore(): number { return this.m_gScore + this.m_hScore; } /** * 是同一个AstarPathStep * */ public isEqual(setp: AstarPathStep): boolean { if(this.m_tilePos.x == setp.m_tilePos.x && this.m_tilePos.y == setp.m_tilePos.y) { return true; } return false; } /** * 是同一个点 * */ public isEqualByPos(pos: egret.Point): boolean { if(this.m_tilePos.x == pos.x && this.m_tilePos.y == pos.y) { return true; } return false; } /** * 设置为开放节点 * */ public setInOpen(flag) { this.m_inOpen = flag; } /** * 设置为关闭节点 * */ public setInClose(flag) { this.m_inClose = flag; } }
/** * 插入 * */ private insertAndSort(step: AstarPathStep) { step.setInOpen(true); var stepFScore = step.fScore(); var openCount = this.m_openList.length; if(openCount == 0) { this.m_openList.push(step); } else { for(var i = 0;i < openCount;i++) { var oneStep = this.m_openList[i]; if(stepFScore <= oneStep.fScore()) { this.m_openList.splice(i,0,step); return } } } }
/** * 返回移动方向 * */ public judgeNextDirection(curPos,nextPos): number { var p = new egret.Point(curPos.x - 1,curPos.y); if(egret.Point.distance(p,nextPos) < 0.1) { return EnumManager.DIRECTION_ENUM.DIR_LEFT; } var p = new egret.Point(curPos.x,curPos.y - 2); if(egret.Point.distance(p,nextPos) < 0.1) { return EnumManager.DIRECTION_ENUM.DIR_UP; } var p = new egret.Point(curPos.x + 1,curPos.y); if(egret.Point.distance(p,nextPos) < 0.1) { return EnumManager.DIRECTION_ENUM.DIR_RIGHT; } var p = new egret.Point(curPos.x,curPos.y + 2); if(egret.Point.distance(p,nextPos) < 0.1) { return EnumManager.DIRECTION_ENUM.DIR_DOWN; } var p = new egret.Point(curPos.x - 1 + curPos.y % 2,curPos.y - 1); if(egret.Point.distance(p,nextPos) < 0.1) { return EnumManager.DIRECTION_ENUM.DIR_UP_LEFT; } var p = new egret.Point(curPos.x + curPos.y%2,curPos.y - 1); if(egret.Point.distance(p,nextPos) < 0.1) { return EnumManager.DIRECTION_ENUM.DIR_UP_RIGHT; } var p = new egret.Point(curPos.x + curPos.y%2,curPos.y + 1); if(egret.Point.distance(p,nextPos) < 0.1) { return EnumManager.DIRECTION_ENUM.DIR_DOWN_RIGHT; } var p = new egret.Point(curPos.x - 1 + curPos.y%2,curPos.y+1); if(egret.Point.distance(p,nextPos) < 0.1) { return EnumManager.DIRECTION_ENUM.DIR_DOWN_LEFT; } console.log("方向解析失败"); //方向解析失败后直接使用角度进行方向解析 var angleSpeed: number = Math.atan2(curPos.y - nextPos.y,curPos.x - nextPos.x); var N = angleSpeed * 180 / Math.PI; if(N <= 20 && N >= -20) { return EnumManager.DIRECTION_ENUM.DIR_LEFT; } else if(N <= 110 && N >= 70) { return EnumManager.DIRECTION_ENUM.DIR_UP; } else if(N <= -170 || N >= 170) { return EnumManager.DIRECTION_ENUM.DIR_RIGHT; } else if(N <= -70 && N >= -110) { return EnumManager.DIRECTION_ENUM.DIR_DOWN; } else if(N < 70 && N > 20) { return EnumManager.DIRECTION_ENUM.DIR_UP_LEFT; } else if(N < 170 && N > 110) { return EnumManager.DIRECTION_ENUM.DIR_UP_RIGHT; } else if(N < -110 && N > -170) { return EnumManager.DIRECTION_ENUM.DIR_DOWN_RIGHT; } else if(N < -20 && N > -70) { return EnumManager.DIRECTION_ENUM.DIR_DOWN_LEFT; } return EnumManager.DIRECTION_ENUM.DIR_DOWN; } }
/** * 获取H值 * */ public getHValue(endStep: AstarPathStep,nextStep: AstarPathStep): number { var to0 = nextStep.m_tilePos.x * Astar.COST_HORIZONTAL + (Math.floor(nextStep.m_tilePos.y) % 2) * Astar.COST_HORIZONTAL / 2; var endTo0 = endStep.m_tilePos.x * Astar.COST_HORIZONTAL + (Math.floor(endStep.m_tilePos.y) % 2) * Astar.COST_HORIZONTAL / 2; return Math.abs(endTo0 - to0) + Math.abs(endStep.m_tilePos.y - nextStep.m_tilePos.y) * Astar.COST_VERTICAL; }
/** * 获取G值 * */ public getGValue(curStep: AstarPathStep,nextStep: AstarPathStep): number { var extaScore = 0; var curPos = curStep.m_tilePos; var nextPos = nextStep.m_tilePos; var G = 0; if(curPos.y == nextPos.y) {//横向移动 G = curStep.m_gScore + Astar.COST_HORIZONTAL; } else if(((curPos.y + 2) == nextPos.y) || ((curPos.y - 2) == nextPos.y)) { G = curStep.m_gScore + Astar.COST_VERTICAL * 2; } else { G = curStep.m_gScore + Astar.COST_DIAGONAL; } return G; }
/** * 获取周围的节点 * */ public getAroundsNode(tpt: egret.Point): Array<egret.Point> { var aroundNodes: Array<egret.Point> = new Array(); var p: egret.Point = new egret.Point(); //左下 p = new egret.Point(tpt.x - 1 + tpt.y % 2,tpt.y + 1); if(this.isWalkable(p) && this.isInClosed(p) == false) { aroundNodes.push(p); } p = new egret.Point(tpt.x + tpt.y % 2,tpt.y - 1); //右上 if(this.isWalkable(p) && this.isInClosed(p) == false) { aroundNodes.push(p); } var p: egret.Point = new egret.Point(); //下 p.x = tpt.x p.y = tpt.y + 2; if(this.isWalkable(p) && this.isInClosed(p) == false) { aroundNodes.push(p); } //左 p = new egret.Point(tpt.x - 1,tpt.y); if(this.isWalkable(p) && this.isInClosed(p) == false) { aroundNodes.push(p); } //右 p = new egret.Point(tpt.x + 1,tpt.y); if(this.isWalkable(p) && this.isInClosed(p) == false) { aroundNodes.push(p); } //上 p = new egret.Point(tpt.x,tpt.y - 2); if(this.isWalkable(p) && this.isInClosed(p) == false) { aroundNodes.push(p); } p = new egret.Point(tpt.x - 1 + (tpt.y % 2),tpt.y - 1); //左上 if(this.isWalkable(p) && this.isInClosed(p) == false) { aroundNodes.push(p); } //右下 p = new egret.Point(tpt.x + (tpt.y % 2),tpt.y + 1); if(this.isWalkable(p) && this.isInClosed(p) == false) { aroundNodes.push(p); } return aroundNodes; }
0 0
- 寻路算法 Astar A星算法
- AStar(A星)算法
- astar寻路算法
- 寻路(AStar/A星/A*)算法
- 寻路(AStar/A星/A*)算法
- 通用Astar算法 通用A星算法 通用A*算法
- Java开源-astar:A 星算法
- A*(AStar)或者也叫A星算法的寻路问题
- Egret寻路算法Astar
- AStar寻径算法
- 寻路(AStar/A星/A*)算法 (上)
- 寻路(AStar/A星/A*)算法 (中)
- Astar A*算法 最短路径算法
- as中Astar自动寻路算法
- 【转】AStar寻路算法文档翻译
- Astar算法
- Astar算法
- AStar算法
- Android图像格式类及图像转换方法
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) B
- 控件背景为四周虚线
- lamp之源码包安装apache
- [kuangbin带你飞]专题四 最短路练习 B POJ 2253
- 寻路算法 Astar A星算法
- 在Unity3D中使用uGUI实现3D旋转特效
- centos6.7安装kvm
- 监听通知栏,back,home键
- css中BFC格式化上下文
- 3D Model & 图片类网站
- [kuangbin带你飞]专题四 最短路练习 C POJ 1797
- php的setcookie使用详解
- Mysql有两种存储引擎:InnoDB与Myisam