public void FindPath(Index start, Index end, DiagonalMode diagonal, BaseTraversal2D traversal2D, PathRequestDelegate callback) { if (!IsValid(start) || !IsValid(end)) { return; } searchGrid.maxPathLength = maxPathLength; bool useThreading = allowThreading; if (useThreading == true) { AsyncPathRequest request = new AsyncPathRequest(searchGrid, start, end, diagonal, traversal2D, (Path path, PathRequestStatus status) => { PathView.setRenderPath(this, path); callback(path, status); }); ThreadManager.Active.asyncRequest(request); } else { PathRequestStatus status; Path result = FindPathImmediate(start, end, out status, diagonal); PathView.setRenderPath(this, result); callback(result, status); } Path FindPathImmediate(Index subStart, Index subEnd, out PathRequestStatus subStatus, DiagonalMode subDiagonal) { searchGrid.maxPathLength = maxPathLength; Path path = null; PathRequestStatus temp = PathRequestStatus.InvalidIndex; searchGrid.FindPath(subStart, subEnd, subDiagonal, traversal2D, (Path result, PathRequestStatus resultStatus) => { temp = resultStatus; if (resultStatus == PathRequestStatus.PathFound) { path = result; PathView.setRenderPath(this, path); } }); subStatus = temp; return(path); } }
public void FindPath(Index start, Index end, DiagonalMode diagonal, BaseTraversal2D traversal, PathRequestDelegate callback) { // Already at the destination if (start.Equals(end)) { callback(null, PathRequestStatus.SameStartEnd); return; } // Get the nodes PathNode startNode = nodeGrid[start.X, start.Y]; PathNode endNode = nodeGrid[end.X, end.Y]; // Clear all previous data ClearSearchData(); // Starting scores startNode.g = 0; startNode.h = provider.heuristic(startNode, endNode); startNode.f = startNode.h; // Add the start node openMap.add(startNode); runtimeMap.add(startNode); orderedMap.Push(startNode); while (openMap.Count > 0) { // Get the front value PathNode value = orderedMap.Pop(); if (value == endNode) { // We have found the path Path result = ConstructPath(searchGrid[endNode.Index.X, endNode.Index.Y]); // Last node if (maxPathLength == -1 || result.NodeCount < maxPathLength) { result.Push(endNode); } // Trigger the delegate with success callback(result, PathRequestStatus.PathFound); // Exit the method return; } else { openMap.remove(value); closedMap.add(value); // Fill our array with surrounding nodes ConstructAdjacentNodes(value, adjacentNodes, diagonal); // Process each neighbor foreach (PathNode pathNode in adjacentNodes) { bool isBetter = false; // Skip null nodes if (pathNode == null) { continue; } // Make sure the node is walkable if (pathNode.IsWalkable == false) { continue; } // Check for occupied if (IsIndexObstacle != null) { if (IsIndexObstacle(pathNode.Index) == true) { continue; } } //检查Traversal if (traversal != null) { if (traversal.Filter(pathNode.TileNode) == false) { continue; } } // Make sure it has not already been excluded if (closedMap.contains(pathNode) == true) { continue; } // Check for custom exclusion descisions if (ValidateConnection(value, pathNode) == false) { continue; } // Calculate the score for the node float score = runtimeMap[value].g + provider.adjacentDistance(value, pathNode) + (pathNode.Weighting * weightingInfluence); bool added = false; // Make sure it can be added to the open map if (openMap.contains(pathNode) == false) { openMap.add(pathNode); isBetter = true; added = true; } else if (score < runtimeMap[pathNode].g) { // The score is better isBetter = true; } else { // The score is not better isBetter = false; } // CHeck if a better score has been found if (isBetter == true) { // Update the search grid searchGrid[pathNode.Index.X, pathNode.Index.Y] = value; // Add the adjacent node if (runtimeMap.contains(pathNode) == false) { runtimeMap.add(pathNode); } // Update the score values for the node runtimeMap[pathNode].g = score; runtimeMap[pathNode].h = provider.heuristic(pathNode, endNode); runtimeMap[pathNode].f = runtimeMap[pathNode].g + runtimeMap[pathNode].h; // CHeck if we added to the open map if (added == true) { // Push the adjacent node to the set orderedMap.Push(pathNode); } else { // Refresh the set orderedMap.Refresh(pathNode); } } } } } // End while // Failure callback(null, PathRequestStatus.PathNotFound); void ClearSearchData() { // Reset all data closedMap.clear(); openMap.clear(); runtimeMap.clear(); orderedMap.Clear(); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { searchGrid[x, y] = null; } } } //构造路径 Path ConstructPath(PathNode current) { // Create the path Path path = new Path(this); // Call the dee construct method DeepConstructPath(current, path); return(path); } void DeepConstructPath(PathNode inputCurrent, Path output) { // Get the node from the search grid PathNode node = searchGrid[inputCurrent.Index.X, inputCurrent.Index.Y]; // Make sure we have a valid node if (node != null) { // Call through reccursive DeepConstructPath(node, output); } // Limit the maximumnumber of nodes in the path if (maxPathLength != -1) { if (output.NodeCount > maxPathLength) { return; } } // Push the node to the path output.Push(inputCurrent); } }
public void FindPath(Index start, Index end, BaseTraversal2D traversal2D, PathRequestDelegate callback) { FindPath(start, end, diagonalMovement, traversal2D, callback); }
public AsyncPathRequest(SearchGrid grid, Index start, Index end, DiagonalMode diagonal, BaseTraversal2D traversal2D, PathRequestDelegate callback) { this.Grid = grid; this.Start = start; this.End = end; this.Diagonal = diagonal; this.Callback = callback; this.Traversal2D = traversal2D; // Create a time stamp TimeStamp = DateTime.UtcNow.Ticks; }