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); } } } } }
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); }
private bool isEndNode(JpsPathNode node) { return(isEndNode(node.cell)); }
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); } }
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); }