Exemple #1
0
 protected void AddNodeToOpenList(AStarNode node)
 {
     node.astarInListType = AStarNodeInListType.Open_List;
     openHeap.Push(node);
     handledDict[node.pos] = node;
 }
Exemple #2
0
        /// <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;
             * */
        }