protected void AddNodeToOpenList(AStarNode node) { node.astarInListType = AStarNodeInListType.Open_List; openHeap.Push(node); handledDict[node.pos] = node; }
/// <summary> /// 构建路径 /// </summary> /// <param name="startCell"></param> /// <param name="startPos"></param> /// <param name="endCell"></param> /// <param name="endPos"></param> /// <returns></returns> public List <Vector2> BuildPath(Cell startCell, Vector2 startPos, Cell endCell, Vector2 endPos) { openList.Clear(); closedList.Clear(); endCell.g = 0; endCell.ComputeH(endPos, startPos); endCell.ComputeF(); endCell.isOpen = false; endCell.parent = null; endCell.sessionId = pathSessionId; openList.Push(endCell); bool isFoundPath = false; //是否找到路径 Cell currNode; //当前节点 Cell adjacentTmp = null; //当前节点的邻接三角型 while (openList.Size > 0) { // 1. 把当前节点从开放列表删除, 加入到封闭列表 currNode = openList.Pop(); closedList.Add(currNode); //路径是在同一个三角形内 if (currNode == startCell) { isFoundPath = true; break; } // 2. 对当前节点相邻的每一个节点依次执行以下步骤: //所有邻接三角型 int adjacentId; for (int i = 0; i < 3; i++) { adjacentId = currNode.linkList[i]; // 3. 如果该相邻节点不可通行或者该相邻节点已经在封闭列表中, // 则什么操作也不执行,继续检验下一个节点; if (adjacentId < 0) //不能通过 { continue; } adjacentTmp = cellList[adjacentId]; if (adjacentTmp != null) { if (adjacentTmp.sessionId != pathSessionId) { // 4. 如果该相邻节点不在开放列表中,则将该节点添加到开放列表中, // 并将该相邻节点的父节点设为当前节点,同时保存该相邻节点的G和F值; adjacentTmp.sessionId = pathSessionId; adjacentTmp.parent = currNode; adjacentTmp.isOpen = true; // remember the side this caller is entering from adjacentTmp.SetAndGetArrivalWall(currNode.index); //计算G值 //当前的g值+(当前边的进入边的中点-当前边出边的中点)的距离 var p1 = Equals(currNode, endCell) ? endPos : currNode.lineList[currNode.arrivalWall].center; adjacentTmp.g = currNode.g + adjacentTmp.ComputeGIncrease(p1, currNode.lineList[i].center); //计算H值 adjacentTmp.ComputeH(adjacentTmp.lineList[adjacentTmp.arrivalWall].center, startPos); //计算F值 adjacentTmp.ComputeF(); //放入开放列表并排序 openList.Push(adjacentTmp); } else { // 5. 如果该相邻节点在开放列表中, // 则判断若经由当前节点到达该相邻节点的G值是否小于原来保存的G值, // 若小于,则将该相邻节点的父节点设为当前节点,并重新设置该相邻节点的G和F值 if (adjacentTmp.isOpen) //已经在openList中 { //计算G值 //当前的g值+(当前边的进入边的中点-当前边出边的中点)的距离 var p1 = Equals(currNode, endCell) ? endPos : currNode.lineList[currNode.arrivalWall].center; float increaseG = adjacentTmp.ComputeGIncrease(p1, currNode.lineList[i].center); if (currNode.g + increaseG < adjacentTmp.g) { adjacentTmp.g = currNode.g; adjacentTmp.parent = currNode; // remember the side this caller is entering from adjacentTmp.SetAndGetArrivalWall(currNode.index); //重新设置在heap中的位置 openList.Remove(adjacentTmp); openList.Push(adjacentTmp); } } else //已在closeList中 { adjacentTmp = null; continue; } } } } } //由网格路径生成路径 return(isFoundPath ? GetPath(startPos, endPos) : null); /*返回cell * List<Vector2> ret = new List<Vector2>(); * foreach (Cell cell in GetCellPath()) * { * ret.Add(cell.Center); * } * return ret; * */ }