Ejemplo n.º 1
0
        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);
            }
        }
Ejemplo n.º 2
0
        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);
            }
        }
Ejemplo n.º 3
0
 public void FindPath(Index start, Index end, BaseTraversal2D traversal2D, PathRequestDelegate callback)
 {
     FindPath(start, end, diagonalMovement, traversal2D, callback);
 }
Ejemplo n.º 4
0
        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;
        }