예제 #1
0
        //寻路评估函数
        private float Heuristic(CStarNode node)
        {
            int dcol = m_endNode.Col - node.Col;
            int drow = m_endNode.Row - node.Row;

            return(Math.Abs(dcol) * m_straightCost + Math.Abs(drow) * m_straightCost);
        }
예제 #2
0
 /// <summary>
 /// 填充本node的值
 /// </summary>
 /// <param name="f">F.</param>
 /// <param name="g">G.</param>
 /// <param name="h">H.</param>
 /// <param name="parent">Parent.</param>
 public void FillValue(float f, float g, float h, CStarNode parent)
 {
     F      = f;
     G      = g;
     H      = h;
     Parent = parent;
 }
예제 #3
0
        /// <summary>
        /// 数据来源AStar 表格地图的直线寻路结果
        /// </summary>
        /// <returns><c>true</c>, if path was found, <c>false</c> otherwise.</returns>
        /// <param name="grid">Grid.</param>
        public bool FindPath(CStarGrid grid)
        {
            CStarNode startNode = grid.StartNode;
            CStarNode endNode   = grid.EndNode;

            SetData(startNode.Col, startNode.Row, endNode.Col, endNode.Row);
            return(Find(grid));
        }
예제 #4
0
        /// <summary>
        /// Finds the path.
        /// result do not has the start node itself
        /// </summary>
        /// <returns><c>true</c>, if path was found, <c>false</c> otherwise.</returns>
        /// <param name="grid">传入需要进行寻路的地图</param>
        /// <param name="closeToDestination">If set to <c>false</c>, 寻路结果不包含终点</param>
        public bool FindPath(CStarGrid grid, bool closeToDestination = false)
        {
            m_grid            = grid;
            m_findClosestNode = closeToDestination;
            m_open.Clear();
            m_closed.Clear();

            m_startNode = m_grid.StartNode;
            m_endNode   = m_grid.EndNode;
            //终点不可通行, 我就不寻路了
            if (!m_endNode.Walkable)
            {
                return(false);
            }

            m_startNode.G = 0;
            m_startNode.H = Heuristic(m_startNode);
            m_startNode.F = m_startNode.G + m_startNode.H;
            bool result = Search();

            return(result);
        }
예제 #5
0
        private void BuildPath()
        {
            m_path.Clear();
            CStarNode node = m_endNode;

            if (!m_findClosestNode)
            {
                m_path.Push(node);
            }

            while (node != m_startNode)
            {
                node = node.Parent;
                m_path.Push(node);
            }

            /* remove the first node which indeed is start node */
            if (m_path.Count > 0)
            {
                m_path.Pop();
            }
        }
예제 #6
0
        //寻路的具体算法
        private bool Search()
        {
            CStarNode node = m_startNode;

            while (node != m_endNode)
            {
                int startCol = Math.Max(0, node.Col - 1);
                int endCol   = Math.Min(m_grid.NumCols - 1, node.Col + 1);
                int startRow = Math.Max(0, node.Row - 1);
                int endRow   = Math.Min(m_grid.NumRows - 1, node.Row + 1);

                //默认我们是寻找九宫格的可通行性
                //但对于2d游戏, 我们想仅仅寻找左右上下
                for (int i = startRow; i <= endRow; i++)
                {
                    for (int j = startCol; j <= endCol; j++)
                    {
                        CStarNode test = m_grid.GetNode(j, i);
                        if (test == node)
                        {
                            continue;
                        }
                        if (!test.Walkable)
                        {
                            continue;
                        }
                        //这里之前是在后面也做f更新了. 但考虑提前到这里会提高效率
                        //如果寻路结果错误, 要移回去
                        if (IsClosed(test))
                        {
                            continue;
                        }

                        //如果仅计算上下左右, 就4个斜角的就不计算了
                        if (m_conn == Connection.Four && node.Col != test.Col && node.Row != test.Row)
                        {
                            continue;
                        }

                        //设置相邻两个格子的通行代价
                        float cost = m_diagCost;
                        if (node.Col == test.Col || node.Row == test.Row)
                        {
                            cost = m_straightCost;
                        }

                        float g = node.G + cost * test.CostMultiplier;
                        float h = Heuristic(test);
                        float f = g + h;
                        if (IsOpen(test))
                        {
                            if (test.F > f)
                            {
                                test.FillValue(f, g, h, node);
                            }
                        }
                        else
                        {
                            test.FillValue(f, g, h, node);
                            m_open.Push(test);
                        }
                    }
                }
                m_closed.Add(node);

                if (m_open.Count == 0)
                {
                    return(false);
                }
                node = m_open.Pop();
            }
            BuildPath();
            return(true);
        }
예제 #7
0
 private bool IsClosed(CStarNode node)
 {
     return(m_closed.Contains(node));
 }
예제 #8
0
 private bool IsOpen(CStarNode node)
 {
     return(m_open.Contains(node));
 }