Пример #1
0
        private void IdentifySuccessors(JpsPathNode node)
        {
            int endX = m_EndNode.cell.row;
            int endY = m_EndNode.cell.col;
            int x    = node.cell.row;
            int y    = node.cell.col;

            FindNeighbors(node);
            int ct = m_Neighbors.Count;

            for (int i = 0; i < ct; ++i)
            {
                CellPos pos       = m_Neighbors[i];
                CellPos jumpPoint = DoJump(pos.row, pos.col, x, y);
                if (jumpPoint.row >= 0 && jumpPoint.col >= 0)
                {
                    int jx = jumpPoint.row;
                    int jy = jumpPoint.col;
                    if (m_CloseSet.ContainsKey(jumpPoint))
                    {
                        continue;
                    }
                    Vector2 pos1 = new Vector2(jx, jy);
                    Vector2 pos2 = new Vector2(x, y);
                    float   d    = (pos1 - pos2).magnitude;
                    float   ng   = node.from_start_cost + d;

                    bool        isOpened = true;
                    JpsPathNode jumpNode;
                    if (!m_OpenNodes.TryGetValue(jumpPoint, out jumpNode))
                    {
                        jumpNode = new JpsPathNode(jumpPoint);
                        isOpened = false;
                    }
                    if (!isOpened || ng < jumpNode.from_start_cost)
                    {
                        jumpNode.from_start_cost = ng;
                        jumpNode.cost            = jumpNode.from_start_cost + CalcHeuristic(jumpPoint);
                        jumpNode.prev            = node;

                        if (!isOpened)
                        {
                            m_OpenQueue.Push(jumpNode);
                            m_OpenNodes.Add(jumpPoint, jumpNode);
                        }
                        else
                        {
                            int index = IndexOpenQueue(jumpNode);
                            m_OpenQueue.Update(index, jumpNode);
                        }
                    }
                }
            }
        }
Пример #2
0
        private int IndexOpenQueue(JpsPathNode node)
        {
            int ct = m_OpenQueue.Count;

            for (int i = 0; i < ct; ++i)
            {
                JpsPathNode n = m_OpenQueue[i];
                if (n.cell.row == node.cell.row && n.cell.col == node.cell.col)
                {
                    return(i);
                }
            }
            return(-1);
        }
Пример #3
0
 private bool isEndNode(JpsPathNode node)
 {
     return(isEndNode(node.cell));
 }
Пример #4
0
        private void FindNeighbors(JpsPathNode node)
        {
            int x = node.cell.row;
            int y = node.cell.col;

            m_Neighbors.Clear();

            JpsPathNode parent = node.prev;

            if (null != parent)
            {
                int px = parent.cell.row;
                int py = parent.cell.col;

                int dx = (x == px ? 0 : (x - px) / Math.Abs(x - px));
                int dy = (y == py ? 0 : (y - py) / Math.Abs(y - py));

                if (dx != 0 && dy != 0)
                {
                    if (IsWalkable(x, y + dy))
                    {
                        m_Neighbors.Add(new CellPos(x, y + dy));
                    }
                    if (IsWalkable(x + dx, y))
                    {
                        m_Neighbors.Add(new CellPos(x + dx, y));
                    }
                    if (IsWalkable(x, y + dy) || IsWalkable(x + dx, y))
                    {
                        m_Neighbors.Add(new CellPos(x + dx, y + dy));
                    }
                    if (!IsWalkable(x - dx, y) && IsWalkable(x, y + dy))
                    {
                        m_Neighbors.Add(new CellPos(x - dx, y + dy));
                    }
                    if (!IsWalkable(x, y - dy) && IsWalkable(x + dx, y))
                    {
                        m_Neighbors.Add(new CellPos(x + dx, y - dy));
                    }
                }
                else
                {
                    if (dx == 0)
                    {
                        if (IsWalkable(x, y + dy))
                        {
                            if (IsWalkable(x, y + dy))
                            {
                                m_Neighbors.Add(new CellPos(x, y + dy));
                            }
                            if (!IsWalkable(x + 1, y))
                            {
                                m_Neighbors.Add(new CellPos(x + 1, y + dy));
                            }
                            if (!IsWalkable(x - 1, y))
                            {
                                m_Neighbors.Add(new CellPos(x - 1, y + dy));
                            }
                        }
                    }
                    else
                    {
                        if (IsWalkable(x + dx, y))
                        {
                            if (IsWalkable(x + dx, y))
                            {
                                m_Neighbors.Add(new CellPos(x + dx, y));
                            }
                            if (!IsWalkable(x, y + 1))
                            {
                                m_Neighbors.Add(new CellPos(x + dx, y + 1));
                            }
                            if (!IsWalkable(x, y - 1))
                            {
                                m_Neighbors.Add(new CellPos(x + dx, y - 1));
                            }
                        }
                    }
                }
            }
            else
            {
                m_Neighbors = CellManager.GetCellAdjacent(node.cell, m_MinCell.row, m_MinCell.col, m_MaxCell.row, m_MaxCell.col);
            }
        }
Пример #5
0
        private List <Vector3> FindPathImpl(CellPos start, CellPos target, Vector3[] addToFirst, Vector3[] addToLast)
        {
            m_OpenQueue.Clear();
            m_OpenNodes.Clear();
            m_CloseSet.Clear();

            m_VisitedCells.Clear();

            m_StartNode = new JpsPathNode(start);
            m_EndNode   = new JpsPathNode(target);

            m_StartNode.cost            = 0;
            m_StartNode.from_start_cost = 0;

            m_OpenQueue.Push(m_StartNode);
            m_OpenNodes.Add(m_StartNode.cell, m_StartNode);

            JpsPathNode curNode = null;

            while (m_OpenQueue.Count > 0)
            {
                curNode = m_OpenQueue.Pop();
                if (m_RecordVisitedCells)
                {
                    m_VisitedCells.Add(curNode.cell);

                    //LogSystem.Debug("row:{0} col:{1} cost:{2} from_start_cost:{3}", curNode.cell.row, curNode.cell.col, curNode.cost, curNode.from_start_cost);
                }
                m_OpenNodes.Remove(curNode.cell);
                m_CloseSet.Add(curNode.cell, true);

                if (isEndNode(curNode))
                {
                    break;
                }

                IdentifySuccessors(curNode);
            }

            List <Vector3> path = new List <Vector3>();

            if (isEndNode(curNode))
            {
                while (curNode != null)
                {
                    JpsPathNode prev = curNode.prev;
                    if (null != prev)
                    {
                        prev.next = curNode;
                    }
                    curNode = prev;
                }
                if (null != addToFirst && addToFirst.Length > 0)
                {
                    path.AddRange(addToFirst);
                }
                curNode = m_StartNode;
                while (curNode != null)
                {
                    Vector3 pt = m_CellMgr.GetCellCenter(curNode.cell.row, curNode.cell.col);
                    path.Add(pt);
                    curNode = curNode.next;
                }
                if (null != addToLast && addToLast.Length > 0)
                {
                    path.AddRange(addToLast);
                }
            }
            return(path);
        }