예제 #1
0
    protected override float h_func(ref NavGraph para_graph, ref NavNode para_nodeID, ref NavNode para_goalNodeID)
    {
        WorldNode wN1 = (WorldNode) para_nodeID;
        WorldNode wN2 = (WorldNode) para_goalNodeID;

        float retHVal = UnityEngine.Vector3.Distance(wN1.getWorldPt(),wN2.getWorldPt());
        return retHVal;
    }
예제 #2
0
 public bool addNode(NavNode para_nwNode)
 {
     bool successFlag = false;
     if( ! vertices.ContainsKey(para_nwNode.getNodeID()))
     {
         vertices.Add(para_nwNode.getNodeID(),para_nwNode);
         successFlag = true;
     }
     return successFlag;
 }
예제 #3
0
 public void SetNextNode()
 {
     if ( Destination != null && Destination.Count > 0)
     {
       NextNode = destination.Dequeue();
       return;
     }
     if (NextNode.type == NavNode.NodeType.Door)  doorsVisited.Add(NextNode);
     SetNextDestination();
 }
예제 #4
0
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        NavNode graph = (NavNode)target;

        if (GUILayout.Button("Insert Node"))
        {
            NavNode node = graph.InsertNode();
            Selection.activeGameObject = node.gameObject;
            SceneView.lastActiveSceneView.FrameSelected();
        }
    }
예제 #5
0
 public SubMove(AgentBase agentBase, NavNode startingNode, object agentStartingData, NavNode destinationNode, Vector3Int dir, bool moveCritical = true, SubMove criticalFor = null, SubMove reliesOn = null, int subMovePriority = 0)
 {
     this.agentStartingData = agentStartingData;
     this.subMovePriority   = subMovePriority;
     this.criticalFor       = criticalFor;
     SetReliesOn(reliesOn);
     finishedExecuting    = false; //todo change this language to finishedAnimation or something more clear, inconsistent use of the word executing.
     this.moveCritical    = moveCritical;
     this.dir             = dir;   //uh, we can just calculate this from destination-starting? I wont jic teleportation becomes like, a move? so we would pass in the previous ... direction entering the teleporter?
     this.agent           = agentBase;
     this.startingNode    = startingNode;
     this.destinationNode = destinationNode;
 }
예제 #6
0
    GameObject GenerateCard(int n)
    {
        GameObject newCard  = Object.Instantiate(baseHex, transform);
        NavNode    newNode  = newCard.GetComponent <NavNode>();
        int        ring     = n % nParamValues;
        int        position = (n / nParamValues) % nParamValues;
        int        color    = ((n / nParamValues) / nParamValues) % nParamValues;
        int        shape    = (((n / nParamValues) / nParamValues) / nParamValues) % nParamValues;

        newNode.Configure(ring, position, color, shape);

        return(newCard);
    }
예제 #7
0
    private IEnumerator LinkNodes(NavNode start)
    {
        foreach (NavNode node in nodes)
        {
            if (!node.Equals(start) && !start.links.ContainsKey(node) && CheckNeighbor(start.pos, node.pos))
            {
                yield return(new WaitForSeconds(0.2f));

                start.Link(node);
                yield return(LinkNodes(node));
            }
        }
    }
예제 #8
0
    void OnDrawGizmosSelected()
    {
        // Draw bounds
        Bounds bounds = globalBounds;

        Gizmos.color = Color.yellow;
        Gizmos.DrawWireCube(bounds.center, bounds.size);

        // Draw nodes
        if (nodes != null)
        {
            Gizmos.color = Color.green;
            foreach (NavNode c in nodes)
            {
                Gizmos.DrawSphere(c.location, 0.1f);

                // Draw connections
                foreach (int n in c.neighbours)
                {
                    if (nodes[n].id < c.id)
                    {
                        Gizmos.DrawLine(nodes[n].location, c.location);
                    }
                }
            }
        }


        // DRAW TEST
        Gizmos.color = Color.green;
        Gizmos.DrawCube(testStart, Vector3.one * 0.5f);
        NavNode a = GetClosestNode(testStart);

        Gizmos.DrawSphere(a.location, 0.5f);


        Gizmos.color = Color.red;
        Gizmos.DrawCube(testEnd, Vector3.one * 0.5f);
        NavNode b = GetClosestNode(testEnd);

        Gizmos.DrawSphere(b.location, 0.5f);

        Gizmos.color = Color.black;
        if (testPath != null)
        {
            foreach (NavNode node in testPath)
            {
                Gizmos.DrawSphere(node.location, 0.25f);
            }
        }
    }
예제 #9
0
    private bool CheckNeighbor(Vector2 pos1, Vector2 pos2)
    {
        Vector2 center  = (pos1 + pos2) / 2f;
        NavNode closest = nodes.OrderBy(i => (center - i.pos).magnitude).FirstOrDefault();

        if (closest.pos.Equals(pos1) || closest.pos.Equals(pos2))
        {
            GameObject   edge = Instantiate(debugEdge, center, Quaternion.identity, transform);
            LineRenderer lr   = edge.GetComponent <LineRenderer>();
            lr.SetPositions(new Vector3[] { pos1, pos2 });
            return(true);
        }
        return(false);
    }
예제 #10
0
 bool CheckCluster(NavNode node1, NavNode node2, NavNode node3)
 {
     int[] props1 = node1.GetProperties();
     int[] props2 = node2.GetProperties();
     int[] props3 = node3.GetProperties();
     for (int i = 0; i < nParams; i++)
     {
         if ((props1[i] + props2[i] + props3[i]) % nParamValues != 0)
         {
             return(false);
         }
     }
     return(true);
 }
    public void ExpandNode(NavNode n)
    {
        RemoveFromFringe(n);

        if (DynamicWeight)
        {
            HeuristicWeight += DynamicWeightStep;
        }

        // loop adjacent
        Dictionary <NavNode, GRID_DIRECTION> neighbors = g_Grid.GetNeighborNodes(n);

        foreach (NavNode neighbor in neighbors.Keys)
        {
            if (neighbor.IsWalkable())
            {
                if (!g_gVal.ContainsKey(neighbor))
                {
                    g_gVal.Add(neighbor, float.MaxValue);
                }
                float val = g_gVal[n] + ComputeNodeCost(n, neighbor, neighbors[neighbor]);
                if (g_gVal[neighbor] > val)
                {
                    g_gVal[neighbor] = val;
                    g_Parents.Remove(neighbor);
                    g_Parents.Add(neighbor, n);
                    if (!g_ClosedList.Contains(neighbor))
                    {
                        if (g_OpenList.Contains(neighbor))
                        {
                            RemoveFromFringe(neighbor);
                        }
                        g_OpenList.Add(neighbor);
                        if (UseBeaconHeuristic)
                        {
                            if (UseBeaconHeuristic && g_Fringe.Count > BeaconFringeLimit)
                            {
                                NavNode last = g_Fringe.Values[g_Fringe.Count - 1];
                                g_gVal.Remove(last);
                                g_Parents.Remove(last);
                                g_OpenList.RemoveWhere(i => i.Equals(last));
                                g_Fringe.RemoveAt(g_Fringe.Count - 1);
                            }
                        }
                        g_Fringe.Add(val + ComputeNodeHeuristic(neighbor), neighbor);
                    }
                }
            }
        }
    }
예제 #12
0
    public void Generate(Map map, NavNode start)
    {
        Reset();

        BrushGraph(start, wallPositions, map.trunkWidth + map.wallWidth, true);
        BrushGraph(start, floorPositions, map.trunkWidth + map.wallWidth / 2, true);
        BrushGraph(start, wallPositions, map.trunkWidth, false);

        ContourPositions(wallContours, wallPositions);

        MapContours(walls, wallContours, map.wallTiles);
        MapPositions(floor, floorPositions, map.floorTile);
        MapShadows(decor, wallContours, map.shadowTiles);
    }
예제 #13
0
        /// <summary>
        /// Coroutine to search for the destination, simply waiting until destination is found.
        /// </summary>

        private IEnumerator FindPathToDestination(NavNode final)
        {
            _pathfinder.Search(_player.CurrentNode, final);
            //Wait for pathfinder to finish its search.
            while (_pathfinder.Running)
            {
                yield return(null);
            }

            if (_pathfinder.PathStatus == PathStatus.success)
            {
                _moveChainCoroutine = StartCoroutine(MoveToDestination(_pathfinder.GetPath()));
            }
        }
예제 #14
0
    public List <Vector2Int> UnwrapPath(NavNode node, out float distance)
    {
        distance = 0.0f;
        List <Vector2Int> result = new List <Vector2Int>();

        while (node != null)
        {
            distance += node.GScore;
            result.Add(node.Data);
            node = node.Parent;
        }

        return(result);
    }
예제 #15
0
    void SetWalkable()
    {
        Vector2 grid_dim = mesh.GetGridDimentions();
        int     i        = 0;

        for (int x = 0; x < grid_dim.x; x++)
        {
            for (int y = 0; y < grid_dim.y; y++)
            {
                NavNode n = mesh.GetNode(x, y);
                n.SetWalkable(!Physics2D.OverlapCircle(n.GetPosiotion(), node_size / 2, obsticle_mask));
            }
        }
    }
예제 #16
0
    public NavNode Graph(float width)
    {
        Vector2 startPos = Eval(0.0);
        Vector2 endPos   = Eval(1.0);

        NavNode start = new NavNode(startPos);
        NavNode end   = new NavNode(endPos);

        start.Link(end);

        GraphRec(width, start, end, 0.0, 1.0);

        return(start);
    }
예제 #17
0
    /// <summary>
    /// calculates distance to root from every other node, must be called after changing the root
    /// </summary>
    /// <param name="root"></param>
    private void CalculateDistances(NavNode root)
    {
        //reset distances
        distancesFromRoot.Clear();
        foreach (NavNode node in MapNodes)
        {
            distancesFromRoot.Add(node, float.MaxValue);
        }

        //set up initial conditions for the search
        List <NavNode> visitedNodes = new List <NavNode>();

        visitedNodes.Add(root);
        Stack <Edge> edgesToVisit = new Stack <Edge>();

        distancesFromRoot[root] = 0;

        foreach (NavNode node in root.ConnectedNodes)
        {
            edgesToVisit.Push(new Edge(root, node));
        }


        //begin calculation of distances
        while (edgesToVisit.Count > 0)
        {
            //take an edge off the stack
            Edge currentEdge = edgesToVisit.Pop();

            //the current node is the one we just traveled to across the edge
            NavNode currentNode = currentEdge.to;

            //reduce the distance if the current route is shorter
            distancesFromRoot[currentNode] = Mathf.Min(
                distancesFromRoot[currentNode],                            //this is the length of the current shortest path back to root from the current node (or it's float.MaxValue)
                distancesFromRoot[currentEdge.from] + currentEdge.length); //but it might be faster to travel through the route we just took instead

            //if we haven't visited that node yet, add its connections as edges to the stack
            if (!visitedNodes.Contains(currentNode))
            {
                foreach (NavNode node in currentNode.ConnectedNodes)
                {
                    edgesToVisit.Push(new Edge(currentNode, node));
                }

                visitedNodes.Add(currentNode);
            }
        }
    }
예제 #18
0
    public void addConnectionSymmetric(NavNode other, int weight, Graph graph)
    {
        switch (graph)
        {
        case Graph.Complete:
            allCons.Add(new NavConnection(other, weight));
            other.allCons.Add(new NavConnection(this, weight));
            break;

        case Graph.Corners:
            cornerCons.Add(new NavConnection(other, weight));
            other.cornerCons.Add(new NavConnection(this, weight));
            break;
        }
    }
예제 #19
0
파일: Map.cs 프로젝트: akollaki/SCRAP-R
            void generateNodes()
            {
                int id = 0;

                for (int i = 0; i < rows; i++)
                {
                    for (int j = 0; j < cols; j++)
                    {
                        var tempNode = new NavNode(id++, i, j);
                        tempNode.setPosition(resolution * (i + 0.5), resolution * (j + 0.5));
                        nodes.Add(tempNode);
                    }
                }
                base.init();
            }
예제 #20
0
    /// <summary>
    /// sets closestNode to be the closest node to this gameobject's transform
    /// </summary>
    private void CalculateNearestNavNode()
    {
        float shortestDistance = float.MaxValue;

        foreach (NavNode node in pathFinder.MapNodes)
        {
            float distance = Vector3.SqrMagnitude(node.transform.position - transform.position);

            if (distance < shortestDistance)
            {
                closestNode      = node;
                shortestDistance = distance;
            }
        }
    }
예제 #21
0
        /// <summary>
        /// Calculates the distance cost between to nodes.
        /// </summary>
        /// <param name="from">The node to start from.</param>
        /// <param name="to">The node to end at.</param>
        /// <returns>The distance cost value.</returns>
        static int GetDistance(NavNode from, NavNode to)
        {
            var connection = new Vector2Int(
                Mathf.Abs(to.Position.x - from.Position.x),
                Mathf.Abs(to.Position.y - from.Position.y));

            var isLargerX = Mathf.Abs(connection.x) > Mathf.Abs(connection.y);

            var larger  = isLargerX ? connection.x : connection.y;
            var smaller = isLargerX ? connection.y : connection.x;

            var distance = (larger - smaller) * 10 + smaller * 14;

            return(distance);
        }
예제 #22
0
 void FollowCourse()
 {
     ship.Engine.MoveToward(destination.Position);
     if (Vector3.Distance(transform.position, destination.Position) <= REACHED_THRESHOLD)
     {
         if (destination.IsLast)
         {
             ship.Remove();
         }
         else
         {
             destination = destination.Next;
         }
     }
 }
예제 #23
0
 /// <summary>
 /// Create a NPC. 
 /// AGXNASK distribution has npAgent move following a Path.
 /// </summary>
 /// <param name="theStage"> the world</param>
 /// <param name="label"> name of </param>
 /// <param name="pos"> initial position </param>
 /// <param name="orientAxis"> initial rotation axis</param>
 /// <param name="radians"> initial rotation</param>
 /// <param name="meshFile"> Direct X *.x Model in Contents directory </param>
 public NPAgent(Stage theStage, string label, Vector3 pos, Vector3 orientAxis,
    float radians, string meshFile)
     : base(theStage, label, pos, orientAxis, radians, meshFile)
 {
     // change names for on-screen display of current camera
     first.Name = "npFirst";
     follow.Name = "npFollow";
     above.Name = "npAbove";
     // IsCollidable = true;  // have NPAgent test collisions
     // path is built to work on specific terrain
     path = new Path(stage, makePath(), Path.PathType.REVERSE); // continuous search path
     stage.Components.Add(path);
     nextGoal = path.NextNode;  // get first path goal
     agentObject.turnToFace(nextGoal.Translation);  // orient towards the first path goal
 }
예제 #24
0
    static NavNode getLowestOpen(List <NavNode> openList)
    {
        float   lowest = float.MaxValue;
        NavNode lNode  = null;

        for (int i = 0; i < openList.Count; i++)
        {
            if (openList[i].pInfo.getCost() < lowest)
            {
                lowest = openList[i].pInfo.getCost();
                lNode  = openList[i];
            }
        }
        return(lNode);
    }
예제 #25
0
    public void push(NavNode myNode)
    {
        size++;
        array[size] = myNode;

        // select min movement or max f sorting
        if (ai)
        {
            aiSiftUp(size);
        }
        else
        {
            siftUp(size);
        }
    }
예제 #26
0
    protected override float g_func(ref NavGraph para_graph, ref NavNode para_node1, ref NavNode para_node2)
    {
        NavEdge reqEdge = para_graph.getEdge(para_node1.getNodeID(),para_node2.getNodeID());

        float retGVal = 0;
        if(reqEdge == null)
        {
            retGVal = float.PositiveInfinity;
        }
        else
        {
            retGVal = reqEdge.getCost();
        }
        return retGVal;
    }
예제 #27
0
        public void CurrentNeighbours_ReturnsLowestWeightedNeighbour()
        {
            var lowestWeightNode = new NavNode {
                Weight = 1
            };
            var higherWeightNode = new NavNode {
                Weight = lowestWeightNode.Weight + 1
            };

            var currentNode = new NavNode {
                Position = new Vector2(1.0f, 5.0f), NeighbourRefs = new [] { lowestWeightNode, higherWeightNode }
            };

            Assert.AreSame(lowestWeightNode, new LowestCostBestFitHeuristic().GetBestNode(currentNode, null, null));
        }
 public bool RemoveFromFringe(NavNode n)
 {
     if (g_OpenList.Contains(n))
     {
         for (int q = 0; q < g_Fringe.Count; q++)
         {
             if (g_Fringe.Values[q].Equals(n))
             {
                 g_OpenList.Remove(n);
                 g_Fringe.RemoveAt(q); return(true);
             }
         }
     }
     return(false);
 }
예제 #29
0
        public void GenerateNavRegionsFromNodes_CreatesExpectedNumberOfRegionsForClashingPoints()
        {
            const int neighbourCount      = 4;
            const int singleNodes         = 30;
            const int expectedRegionCount = 5;

            var     nodesToAllocate = new List <NavNode>();
            var     neighbourNodes  = new List <NavNode>(neighbourCount);
            NavNode priorNode       = null;

            for (int j = 0; j < expectedRegionCount; j++)
            {
                for (int i = 0; i < singleNodes; i++)
                {
                    var newNode = new NavNode();

                    for (int k = 0; k < neighbourCount - 1; k++)
                    {
                        var newNeighbour = new NavNode();
                        neighbourNodes.Add(newNeighbour);
                    }

                    if (priorNode != null)
                    {
                        var updatedPriorNeighbours = priorNode.NeighbourRefs.ToList();
                        updatedPriorNeighbours.Add(newNode);

                        priorNode.NeighbourRefs = updatedPriorNeighbours.ToArray();
                        neighbourNodes.Add(priorNode);
                    }

                    newNode.NeighbourRefs = neighbourNodes.ToArray();

                    nodesToAllocate.Add(newNode);

                    foreach (var neighbourNode in neighbourNodes)
                    {
                        nodesToAllocate.Add(neighbourNode);
                    }

                    neighbourNodes.Clear();

                    priorNode = newNode;
                }
            }

            Assert.AreEqual(1, NavRegionGenerationFunctions.GenerateNavRegionsFromNodes(nodesToAllocate, singleNodes * neighbourCount).Count);
        }
예제 #30
0
 void OnDrawGizmos()
 {
     if (grid != null)
     {
         NavNode playerNode = GetNodeFromWorld(PlayerController.playerTrans.position);
         foreach (NavNode n in grid)
         {
             Gizmos.color = (n.walkable) ? new Color(1, 1, 1, 0.2f) : Color.red;
             if (playerNode == n)
             {
                 Gizmos.color = Color.cyan;
             }
             Gizmos.DrawCube(n.worldPosition, Vector3.one * (nodeDiameter - .05f));
         }
     }
 }
예제 #31
0
 public void SetStartEnd(GameObject marker)
 {
     if (!startDefined)
     {
         myStart      = marker.GetComponent <NavNode>();
         startDefined = true;
         uiController.NavigationPanelControl(1);
     }
     else
     {
         myEnd        = marker.GetComponent <NavNode>();
         startDefined = false;
         StartPathCalculation();
         uiController.NavigationPanelControl(2);
     }
 }
예제 #32
0
파일: PathFinder.cs 프로젝트: justi1jc/FPS
    /* Creates the vertices for this map. */
    public IEnumerator Initialize(Vector3 max, Vector3 min)
    {
        for (float x = min.x; x < max.x; x += boxSize)
        {
            for (float z = min.y; z < max.z; z += boxSize)
            {
                NavNode node = new NavNode();
                node.id = nextId;
                nextId++;
                node.pos         = new Vector3(x, 0f, z);
                node.initialized = false;
            }
        }

        yield return(new WaitForSeconds(0f));
    }
        public void NullDestination_ReturnsNull()
        {
            var currentNode = new NavNode
            {
                Position      = new Vector2(10.0f, 1.0f),
                NeighbourRefs = new[]
                {
                    new NavNode
                    {
                        Position = new Vector2(12.0f, 1.0f)
                    }
                }
            };

            Assert.IsNull(new ClosestNodeBestFitHeuristic().GetBestNode(currentNode, null, null));
        }
예제 #34
0
    public override bool Equals(object obj)
    {
        if (obj == null)
        {
            return(false);
        }

        if (this.GetType() != obj.GetType())
        {
            return(false);
        }

        NavNode other = (NavNode)obj;

        return(Data == other.Data);
    }
예제 #35
0
        public async Task <bool> AddAsync(NavNodeDto dto)
        {
            try
            {
                using (var dbContext = _dbContextScopeFactory.Create())
                {
                    var entity = NavNode.Create(dto);
                    _navNodeRepository.Add(entity);
                    await dbContext.SaveChangesAsync();

                    return(true);
                }
            }
            catch (Exception ex) { }
            return(false);
        }
예제 #36
0
        /// <summary>
        /// Calculate the distance between a node n
        /// and its neighbor m. It's either
        /// 150 or 150 * \sqrt{2}
        /// </summary>
        /// <param name="n">a node n</param>
        /// <param name="m">neighbor of m</param>
        /// <returns>the distance between 2 nodes</returns>
        public double CalculateDistanceFromSource(NavNode n, NavNode m)
        {
            // first we convert their actual location
            // to node on graph. Then we truncate
            // all the decimal points. So it returns
            // a pair of (x, z) -> (512, 512)
            int xN = (int)(n.Translation.X / 150);
            int zN = (int)(n.Translation.Z / 150);

            int xM = (int)(m.Translation.X / 150);
            int zM = (int)(m.Translation.Z / 150);

            // next we find their location
            int temp = Math.Abs(xN - xM) + Math.Abs(zN - zM);
            // this is corner
            if (temp == 2)
                return stage.Spacing * Math.Sqrt(2);
            else
                return stage.Spacing;
        }
예제 #37
0
 public bool addNode(NavNode para_nwNode)
 {
     return vertices.addNode(para_nwNode);
 }
        public void Update(double elapsedTime)
        {
            _nodeUI.ForEach(x => x.Update(elapsedTime, _input.Mouse.Position));

            if (_input.Mouse.LeftPressed)
            {
                NodeUI node = _nodeUI.Find(x => x.HasFocus());

                if (node != null)
                {
                    if (_start == null)
                    {
                        _start = node.Node;
                    }
                    else if (_end == null)
                    {
                        _end = node.Node;
                        _astar.FindPath(_start, _end);
                        _astar.Path.Reverse();
                    }
                    else
                    {
                        // Time to reset.
                    }
                }
            }
        }
예제 #39
0
        /// <summary>
        ///       ----------------
        ///       - A* Algorithm -
        ///       ----------------
        ///       
        /// OPEN = priority queue contain START
        /// CLOSED = empty set
        /// 
        /// while lowest rank in OPEN is not the GOAL:
        ///     current = remove lowest rank item from OPEN
        ///     add current to CLOSED
        ///     
        ///     for neighbors of current
        ///         cost = g(current) + movement_cost(current, neighbor)
        ///         
        ///         if neighbor in OPEN and cost less than g(neighbor)
        ///             remove neighbor from OPEN, because new path is better
        ///             
        ///         if neighbor in CLOSED and cost less than g(neighbor)
        ///             remove neighbor from CLOSED
        ///             
        ///         if neighbor not in OPEN and neighbor not in CLOSED
        ///             set g(neighbor) to cost
        ///             add neighbor to OPEN
        ///             set priority queue rank to g(neighbor) + h(neighbor)
        ///             set neighbor's parent to current
        ///             
        /// 
        /// reconstruct reverse path from goal to start
        /// by following parent pointers
        ///  
        /// </summary>
        /// <param name="startPostion">start</param>
        /// <param name="goalPosition">destination</param>
        /// <param name="nodeType">color of node</param>
        /// <returns></returns>
        private List<NavNode> MakeAStarPath(Vector3 startPostion, Vector3 goalPosition, NavNode.NavNodeEnum nodeType)
        {
            /**
             * A* implementation
             *      Summary:
             *              1) Add the starting node to the open set
             *              2) Repeat the following:
             *                      a) Look for the lowest F cost on the open set.
             *                      b) Move it to the closed set
             *                      c) For each of the 8 adjacency node to the current node:
             *                              + If it is NOT walkable or if it is on the CLOSED SET, just ignore it.
             *                              + Otherwise:
             *                                  - If it is NOT on the OPEN SET, add it to the OPEN SET. Make the "current node" as
             *                                    parent of this adjacency node. Record F, G, H for this node.
             *                                  - If it is on the OPEN SET already, check to see if this path to that square is
             *                                    better using G cost as the measure. A lower G means that this is a better path.
             *                                    If so, change the parent of the node to the "current node", and recalculate
             *                                    the G and F cost of the node.
             *                      d) Stop when we:
             *                              + Add the goal node to the closed set, in which case the path has been found.
             *                              + Fail to find the goal node, and the open set is empty. In this case, there is NO path.
             */
            // spacing between node on map (= 150)
            int spacing = stage.Terrain.Spacing;

            /**
             * A* path
             *      this is our final path
             */
            List<NavNode> path = new List<NavNode>();

            /**
             * The starting point
             */
            NavNode start = new NavNode(startPostion);
            start.DistanceFromSource = 0.0;
            start.DistanceToGoal = 0.0;
            start.Distance = 0.0;
            start.Parent = null;

            /**
             * The goal
             */
            NavNode goal = new NavNode(goalPosition);
            goal.DistanceFromSource = 0.0;
            goal.DistanceToGoal = 0.0;
            goal.Distance = 0.0;
            goal.Parent = null;

            // open set
            PriorityQueue<NavNode> openSet = new PriorityQueue<NavNode>();

            // close set
            PriorityQueue<NavNode> closedSet = new PriorityQueue<NavNode>();

            // add starting point to open set (part 1)
            openSet.Add(start);

            while (!openSet.Empty) {

                // get the current node with lowest cost F and remove it from open set
                NavNode current = openSet.Pop();

                // add current to close set
                closedSet.Add(current);

                // if it's equal to our goal, we're done (part d)
                if (current.IsSameLocation(goal)) {
                    while (current.Parent != null) {
                        path.Add(current);
                        current.Navigatable = nodeType;
                        current = current.Parent;
                    }
                    path.Reverse();
                    return path;
                }
                else {
                    // for each of the 8 adjacency neighbors
                    // NOTE: the neighbor list already removed un-walkable nodes
                    List<NavNode> neighbors = GetNeighbors(current.Translation);

                    foreach (NavNode n in neighbors) {
                        // if it's on the closed set, just ignore it
                        if (IsNodeIn(n, closedSet)) {
                            continue;
                        }
                        else {
                            if (!IsNodeIn(n, openSet)) {
                                // make the "current node" as parent of this neighbor
                                n.Parent = current;
                                // record new F, G, H
                                n.DistanceFromSource = current.DistanceFromSource + CalculateDistanceFromSource(current, n);
                                n.DistanceToGoal = CalculateHeuristicDinstanceToGoal(n, goal);
                                n.Distance = n.DistanceFromSource + n.DistanceToGoal;

                                // add this neighbor to the OPEN SET
                                openSet.Add(n);
                            }
                            else { // it's already on the OPEN SET
                                double costFromThisPathToN = current.DistanceFromSource + CalculateDistanceFromSource(current, n);
                                // we have a better path, going from "current node"
                                if (costFromThisPathToN < n.DistanceFromSource) {
                                    // recalculate G and F for this neighbor
                                    n.Parent = current;
                                    n.DistanceFromSource = costFromThisPathToN;
                                    n.Distance = n.DistanceFromSource + n.DistanceToGoal;
                                }
                            }
                        }
                    }
                }
            }

            return path;
        }
예제 #40
0
        private void HandleTreasureMode()
        {
            if (treasurePathQueue.Count == 0) {
                // switch mode
                mode = ModeEnum.EXPLORING;
                npAgentGameMode = Stage.GameMode.NP_AGENT_EXPLORING;

                // resume to previous exploring path if any
                if (previousPath != null && !previousPath.Done) {
                    currentPath = previousPath;
                    // nextGoal = currentPath.NextNode;
                    // agentObject.TurnToFace(nextGoal.Translation);
                }
                else {
                    HandleExploringMode();
                }
            }
            else {
                // get another path from treasure path queue
                currentPath = treasurePathQueue.Dequeue();
                // add path to stage two show trace
                stage.Components.Add(currentPath);
                // get first path goal
                nextGoal = currentPath.NextNode;
                // orient towards the first path goal
                agentObject.TurnToFace(nextGoal.Translation);
            }
        }
예제 #41
0
        /// <summary>
        /// Here we allow switching from regular path to treasure path if only if 
        /// the treasure path is not done, otherwise it will do nothing (disable)
        /// </summary>
        private void ChangeToTreasurePath(int idx)
        {
            AddNewTreasurePath(idx);

            // save the previous path if any
            if (mode == ModeEnum.EXPLORING) {
                if (!currentPath.Done) {
                    previousPath = currentPath;
                }
            }

            // update the mode
            mode = ModeEnum.TREASURE_HUNTING;
            // set new path
            currentPath = treasurePathQueue.Dequeue();
            // add path to stage
            stage.Components.Add(currentPath);
            // get the first target
            nextGoal = currentPath.NextNode;
            // orient towards the first path goal
            agentObject.TurnToFace(nextGoal.Translation);
        }
예제 #42
0
	// Finds a path between the start node and the destination node using A* pathfinding algorithm
	public List<NavNode> AStarSearch(NavNode start, NavNode destination){

		// Initialize the necessary lists and variables for A* pathfinding
		List<NavNode> all = new List<NavNode>();
		all.Add(start);
		List<NavNode> closed = new List<NavNode>();
		List<NavNode> open = new List<NavNode>(all);
		List<NavNode> path = new List<NavNode>();
		//float totalCost = 0;
		//float currentBest = 0;

		while (open[0] != destination){
			NavNode lowest = open[0];

			// Find the node with the lowest value in open
			int openCount = open.Count;
			for (int i = 0; i < openCount; i++){
				NavNode currentNode = open[i];
				if (currentNode.GetCostToHere() < lowest.GetCostToHere()){
					lowest = currentNode;
				}
			}

			// Remove the current lowest from open and add it to the closed since it is being visited
			open.Remove (lowest);
			closed.Add (lowest);

			// Iterate through the neighbors of the selected node
			int lowestNeighborCount = lowest.GetNeighborNodes().Count;
			for (int i = 0; i < lowestNeighborCount; i++){
				NavNode currentNeighbor = lowest.GetNeighborNodes()[i];

				// Calculate the cost as the distance between the current node and the current neighbor
				float cost = lowest.GetCostToHere() + Vector3.Distance(lowest.transform.position, currentNeighbor.transform.position);
				if (open.Contains(currentNeighbor) && cost < currentNeighbor.GetCostToHere()) {
					open.Remove(currentNeighbor);
				}
				if (closed.Contains(currentNeighbor) && cost < currentNeighbor.GetCostToHere()) {
					closed.Remove(currentNeighbor);
				}
				if (!open.Contains(currentNeighbor) && !closed.Contains(currentNeighbor)) {
					//currentBest = cost;

					// If the open list is empty, add the current neighbor to the open list
					if (open.Count == 0){
						open.Add(currentNeighbor);
					}
					// Otherwise, place the node in the open list at the appropriate position according to its cost
					else {
						bool addedToOpen = false;
						int count = open.Count;
						for (int j = 0; j < count; j++){
							if (cost < open[j].GetCostToHere()){
								open.Insert(j, currentNeighbor);
								addedToOpen = true;
								break;
							}
						}
						if (!addedToOpen){
							open.Insert (open.Count, currentNeighbor);
						}
					}
					
					// Set the cost and parent of the current neighbor
					currentNeighbor.SetCostToHere(cost);
					currentNeighbor.SetParentNode(lowest);
				}
			}
		}

		// Once finished, determine what the path is by looking at the parent nodes and insert them into the path in the proper order
		NavNode node = destination;
		while (node.GetParentNode() != start){
			path.Insert(0, node);
			node = node.GetParentNode();
		}
		path.Insert(0, node);
		return path;
	}
예제 #43
0
        private int snapDistance = 20; // this should be a function of step and stepSize

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Create a NPC. 
        /// AGXNASK distribution has npAgent move following a Path.
        /// </summary>
        /// <param name="theStage"> the world</param>
        /// <param name="label"> name of </param>
        /// <param name="pos"> initial position </param>
        /// <param name="orientAxis"> initial rotation axis</param>
        /// <param name="radians"> initial rotation</param>
        /// <param name="meshFile"> Direct X *.x Model in Contents directory </param>
        public NPAgent(Stage theStage, string label, Vector3 pos, Vector3 orientAxis, 
      float radians, string meshFile)
            : base(theStage, label, pos, orientAxis, radians, meshFile)
        {
            // change names for on-screen display of current camera
              first.Name =  "npFirst";
              follow.Name = "npFollow";
              above.Name =  "npAbove";
              // path is built to work on specific terrain, make from int[x,z] array pathNode
              path = new Path(stage, pathNode, Path.PathType.LOOP); // continuous search path
              stage.Components.Add(path);
              nextGoal = path.NextNode;  // get first path goal
              agentObject.turnToFace(nextGoal.Translation);  // orient towards the first path goal
            // set snapDistance to be a little larger than step * stepSize
            snapDistance = (int) (1.5 * (agentObject.Step * agentObject.StepSize));
        }
예제 #44
0
        /// <summary>
        /// Simple path following.  If within "snap distance" of a the nextGoal (a NavNode) 
        /// move to the NavNode, get a new nextGoal, turnToFace() that goal.  Otherwise 
        /// continue making steps towards the nextGoal.
        /// </summary>
        public override void Update(GameTime gameTime)
        {
            KeyboardState keyboardState = Keyboard.GetState();
               if ((keyboardState.IsKeyDown(Keys.N) && !oldKeyboardState.IsKeyDown(Keys.N)) && currentState == UpdateState.PATH_FOLLOWING)
              currentState = UpdateState.TREASURE_GOAL;  // toggle NPAgent update state.
               float distance;
               switch(currentState)
               {
               case UpdateState.PATH_FOLLOWING :
               agentObject.turnToFace(nextGoal.Translation);  // adjust to face nextGoal every move
                // See if at or close to nextGoal, distance measured in 2D xz plane
                distance = Vector3.Distance(
                    new Vector3(nextGoal.Translation.X, 0, nextGoal.Translation.Z),
                    new Vector3(agentObject.Translation.X, 0, agentObject.Translation.Z));
                stage.setInfo(15, stage.agentLocation(this));
              stage.setInfo(16,
                    string.Format("          nextGoal ({0:f0}, {1:f0}, {2:f0})  distance to next goal = {3,5:f2})",
                        nextGoal.Translation.X/stage.Spacing, nextGoal.Translation.Y, nextGoal.Translation.Z/stage.Spacing, distance) );
              if (distance  <= snapDistance)  {
                 // snap to nextGoal and orient toward the new nextGoal
                 nextGoal = path.NextNode;
                 // agentObject.turnToFace(nextGoal.Translation);
                 }
               oldKeyboardState = keyboardState;    // Update saved state.
              base.Update(gameTime);  // Agent's Update();
               break;

               case UpdateState.TREASURE_GOAL :
               agentObject.turnToFace(new Vector3(67050,100,67950));  // adjust to face nextGoal every move
                // See if at or close to nextGoal, distance measured in 2D xz plane
                distance = Vector3.Distance(
                    new Vector3(67050,0,67950),
                    new Vector3(agentObject.Translation.X, 0, agentObject.Translation.Z));
                stage.setInfo(15, stage.agentLocation(this));
              //stage.setInfo(16,
              //      string.Format("          nextGoal ({0:f0}, {1:f0}, {2:f0})  distance to next goal = {3,5:f2})",
              //          nextGoal.Translation.X/stage.Spacing, nextGoal.Translation.Y, nextGoal.Translation.Z/stage.Spacing, distance) );
              if (distance  <= 300)  {
                 // snap to nextGoal and orient toward the new nextGoal
                 //nextGoal = path.NextNode;
                 currentState = UpdateState.PATH_FOLLOWING;
                 // agentObject.turnToFace(nextGoal.Translation);
                 }
               oldKeyboardState = keyboardState;    // Update saved state.
              base.Update(gameTime);  // Agent's Update();
               break;
               }
        }
예제 #45
0
	public void SetParentNode(NavNode newParent){
		m_parentNode = newParent;
	}
예제 #46
0
    public List<NavNode> getChildNodesAtHopDistance(NavNode para_sourceNode,
	                                                int para_distanceFromSrc,
	                                                HashSet<int> para_untraversibleTypes,
	                                                HashSet<int> para_untraversibleNodes)
    {
        // Uses modified Breadth First Search.
        List<NavNode> retList = new List<NavNode>();

        int depthLevel = 0;
        List<int> candidateNodeIDs = new List<int>();
        List<int> nwCandidateNodeIDs = new List<int>();
        HashSet<int> seenNodes = new HashSet<int>();
        candidateNodeIDs.Add(para_sourceNode.getNodeID());

        if(para_distanceFromSrc > 0)
        {
            do
            {
                for(int i=0; i<candidateNodeIDs.Count; i++)
                {
                    int cNodeID = candidateNodeIDs[i];

                    if( ! seenNodes.Contains(cNodeID))
                    {
                        seenNodes.Add(cNodeID);
                        NavNode cNode = getNode(cNodeID);
                        HashSet<int> cNodeNeighbours = cNode.getAllNeighbourIDs();

                        foreach(int neighbourID in cNodeNeighbours)
                        {
                            bool isValid = true;
                            if(depthLevel == (para_distanceFromSrc-1))
                            {
                                if(seenNodes.Contains(neighbourID))
                                {
                                    isValid = false;
                                }
                            }

                            if(para_untraversibleNodes != null)
                            {
                                if(para_untraversibleNodes.Contains(neighbourID))
                                {
                                    isValid = false;
                                }
                            }

                            if(para_untraversibleTypes != null)
                            {
                                if(para_untraversibleTypes.Contains(getNode(neighbourID).getNodeType()))
                                {
                                    isValid = false;
                                }
                            }

                            if(isValid)
                            {
                                nwCandidateNodeIDs.Add(neighbourID);
                            }
                        }
                    }
                }

                candidateNodeIDs.Clear();
                candidateNodeIDs = nwCandidateNodeIDs;
                nwCandidateNodeIDs = new List<int>();

                depthLevel++;
            }
            while((depthLevel < para_distanceFromSrc)&&(candidateNodeIDs.Count > 0));
        }

        for(int i=0; i<candidateNodeIDs.Count; i++)
        {
            retList.Add(getNode(candidateNodeIDs[i]));
        }

        return retList;
    }
예제 #47
0
        /// <summary>
        /// Calculate the distance between a node n
        /// and its goal using Manhattan formula.
        /// We count the number squares vertically and 
        /// horizontally to from n to the goal
        /// </summary>
        /// <param name="n">a node on graph</param>
        /// <param name="goal">a goal</param>
        /// <returns>their distance</returns>
        public double CalculateHeuristicDinstanceToGoal(NavNode n, NavNode goal)
        {
            // first we convert their actual location
            // to node on graph. Then we truncate
            // all the decimal points. So it returns
            // a pair of (x, z) -> (512, 512)
            int xN = (int)(n.Translation.X / 150);
            int zN = (int)(n.Translation.Z / 150);

            int xGoal = (int)(goal.Translation.X / 150);
            int zGoal = (int)(goal.Translation.Z / 150);

            // then we take the number squares times 150
            return stage.Spacing * (Math.Abs(xN - xGoal) + Math.Abs(zN - zGoal));
        }
예제 #48
0
        private bool IsValidMove(NavNode[] grid, int ax, int ay, int bx, int by)
        {
            if(grid[bx + by * _map.Width]._cost == BlockerCost)
                return false;

            // Diagonal movement must NOT go past any blocker neighbors
            if(ax != bx && ay != by)
            {
                if(	grid[ax + by * _map.Width]._cost == BlockerCost ||
                    grid[bx + ay * _map.Width]._cost == BlockerCost)
                    return false;
            }

            return true;
        }
예제 #49
0
        /// <summary>
        /// Get all neighbors of a node on map.
        /// There are 512 x 512 nodes
        /// and 8 possible neighbors for each node
        /// </summary>
        /// <param name="node">a position on map</param>
        /// <returns></returns>
        public List<NavNode> GetNeighbors(Vector3 node)
        {
            // initialize collection
            List<NavNode> neighbors = new List<NavNode>();

            // convert to x, z coordinate to map to (512, 512)
            int x = (int)(node.X / 150);
            int z = (int)(node.Z / 150);
            int spacing = stage.Spacing;
            Terrain terrain = stage.Terrain;

            /*
             *      8 possible adjacent neighbors
             * ----------------------------------------------------
             * | (x - 1, z - 1) | (x, z - 1)    | (x + 1, z - 1)  |
             * ----------------------------------------------------
             * | (x - 1, z)     | (x, z)        | (x + 1, z)      |
             * ----------------------------------------------------
             * | (x - 1, z + 1) | (x, z + 1)    | (x + 1, z + 1)  |
             * ----------------------------------------------------
             */
            // left
            if (IsInRange(x - 1, z)) {
                Vector3 left = new Vector3((x - 1) * spacing, terrain.SurfaceHeight(x - 1, z), z * spacing);
                if (IsWalkable(left)) {
                    NavNode n = new NavNode(left, NavNode.NavNodeEnum.A_STAR);
                    neighbors.Add(n);
                }
            }

            // right
            if (IsInRange(x + 1, z)) {
                Vector3 right = new Vector3((x + 1) * spacing, terrain.SurfaceHeight(x + 1, z), z * spacing);
                if (IsWalkable(right)) {
                    NavNode n = new NavNode(right, NavNode.NavNodeEnum.A_STAR);
                    neighbors.Add(n);
                }
            }

            // up
            if (IsInRange(x, z - 1)) {
                Vector3 up = new Vector3(x * spacing, terrain.SurfaceHeight(x, z - 1), (z - 1) * spacing);
                if (IsWalkable(up)) {
                    NavNode n = new NavNode(up, NavNode.NavNodeEnum.A_STAR);
                    neighbors.Add(n);
                }
            }

            // down
            if (IsInRange(x, z + 1)) {
                Vector3 down = new Vector3(x * spacing, terrain.SurfaceHeight(x, z + 1), (z + 1) * spacing);
                if (IsWalkable(down)) {
                    NavNode n = new NavNode(down, NavNode.NavNodeEnum.A_STAR);
                    neighbors.Add(n);
                }
            }

            // upper left
            if (IsInRange(x - 1, z - 1)) {
                Vector3 upperLeft = new Vector3((x - 1) * spacing, terrain.SurfaceHeight(x - 1, z - 1), (z - 1) * spacing);
                if (IsWalkable(upperLeft)) {
                    NavNode n = new NavNode(upperLeft, NavNode.NavNodeEnum.A_STAR);
                    neighbors.Add(n);
                }
            }

            // upper right
            if (IsInRange(x + 1, z - 1)) {
                Vector3 upperRight = new Vector3((x + 1) * spacing, terrain.SurfaceHeight(x + 1, z - 1), (z - 1) * spacing);
                if (IsWalkable(upperRight)) {
                    NavNode n = new NavNode(upperRight, NavNode.NavNodeEnum.A_STAR);
                    neighbors.Add(n);
                }
            }

            // lower left
            if (IsInRange(x - 1, z + 1)) {
                Vector3 lowerLeft = new Vector3((x - 1) * spacing, terrain.SurfaceHeight(x - 1, z + 1), (z + 1) * spacing);
                if (IsWalkable(lowerLeft)) {
                    NavNode n = new NavNode(lowerLeft, NavNode.NavNodeEnum.A_STAR);
                    neighbors.Add(n);
                }
            }

            // lower Right
            if (IsInRange(x + 1, z + 1)) {
                Vector3 lowerRight = new Vector3((x + 1) * spacing, terrain.SurfaceHeight(x + 1, z + 1), (z + 1) * spacing);
                if (IsWalkable(lowerRight)) {
                    NavNode n = new NavNode(lowerRight, NavNode.NavNodeEnum.A_STAR);
                    neighbors.Add(n);
                }
            }

            return neighbors;
        }
예제 #50
0
        public bool Rebuild(IEnumerable<Point> blockers)
        {
            NavNode[] newGrid = new NavNode[_map.Width * _map.Height];
            PriorityQueueB<int> open = new PriorityQueueB<int>( (a,b) => newGrid[a]._cost.CompareTo(newGrid[b]._cost) );
            open.Push(_targetX + _targetY * _map.Width);

            for(int i = 0; i < newGrid.Length; ++i)
            {
                newGrid[i]._cost = _map.Blocks[i].Type == BlockType.Solid ? BlockerCost : 0;
                newGrid[i]._nextIndex = -1;
            }

            if(blockers != null)
            {
                foreach(Point p in blockers)
                {
                    newGrid[p.X + p.Y * _map.Width]._cost = BlockerCost;
                }
            }

            while(open.Count > 0)
            {
                // Get the lowest cost open node
                int nodeIndex = open.Pop();
                int nodeX = nodeIndex % _map.Width;
                int nodeY = nodeIndex / _map.Width;

                for(int i = 0; i < 8; ++i)
                {
                    int nextNodeX = nodeX + NeighborLookups[i*2+0];
                    int nextNodeY = nodeY + NeighborLookups[i*2+1];

                    if(nextNodeX < 0 || nextNodeX >= _map.Width || nextNodeY < 0 || nextNodeY >= _map.Height)
                        continue;

                    int nextNodeIndex = nextNodeX + nextNodeY * _map.Width;

                    int nextCost = newGrid[nodeIndex]._cost + (i >= 4 ? 14 : 10);

                    if(IsValidMove(newGrid, nodeX, nodeY, nextNodeX, nextNodeY))
                    {
                        // If the neighbor is not already visited, and walkable
                        if(newGrid[nextNodeIndex]._nextIndex == -1)
                        {
                            newGrid[nextNodeIndex]._cost = nextCost;
                            newGrid[nextNodeIndex]._nextIndex = nodeIndex;

                            // add it to the open queue
                            open.Push(nextNodeIndex);
                        }
                        else // Update the neighbor if this is a shorter path
                            if(nextCost < newGrid[nextNodeIndex]._cost)
                            {
                                newGrid[nextNodeIndex]._cost = nextCost;
                                newGrid[nextNodeIndex]._nextIndex = nodeIndex;
                            }
                    }
                }
            }

            // Verify that all enemy spawn points can reach the target.
            if( 0 != _map.EnemySpawns.Count(sp => newGrid[sp.BlockX + sp.BlockY * _map.Width]._nextIndex < 0))
            {
                return false;
            }

            Grid = newGrid;

            return true;
        }
예제 #51
0
 private void HandleExploringMode()
 {
     if (explorePathQueue.Count == 0) {
         done = true;
         npAgentGameMode = Stage.GameMode.NP_AGENT_TREASURE_STOP;
     }
     else {
         // get another path from explore path queue
         currentPath = explorePathQueue.Dequeue();
         // get first path goal
         nextGoal = currentPath.NextNode;
         // orient towards the first path goal
         agentObject.TurnToFace(nextGoal.Translation);
     }
 }
예제 #52
0
 /// <summary>
 /// A very simple limited random walk.  Repeatedly moves skipSteps forward then
 /// randomly decides how to turn (left, right, or not to turn).  Does not move
 /// very well -- its just an example...
 /// </summary>
 public override void Update(GameTime gameTime)
 {
     stage.setInfo(15,
        string.Format("npAvatar:  Location ({0:f0},{1:f0},{2:f0})  Looking at ({3:f2},{4:f2},{5:f2})",
           agentObject.Translation.X, agentObject.Translation.Y, agentObject.Translation.Z,
           agentObject.Forward.X, agentObject.Forward.Y, agentObject.Forward.Z));
     stage.setInfo(16,
        string.Format("nextGoal:  ({0:f0},{1:f0},{2:f0})", nextGoal.Translation.X, nextGoal.Translation.Y, nextGoal.Translation.Z));
     // See if at or close to nextGoal, distance measured in the flat XZ plane
     float distance = Vector3.Distance(
        new Vector3(nextGoal.Translation.X, 0, nextGoal.Translation.Z),
        new Vector3(agentObject.Translation.X, 0, agentObject.Translation.Z));
     if (distance <= snapDistance)
     {
         stage.setInfo(17, string.Format("distance to goal = {0,5:f2}", distance));
         // snap to nextGoal and orient toward the new nextGoal
         nextGoal = path.NextNode;
         agentObject.turnToFace(nextGoal.Translation);
         if (path.Done)
             stage.setInfo(18, "path traversal is done");
         else
         {
             turnCount++;
             stage.setInfo(18, string.Format("turnToFace count = {0}", turnCount));
         }
     }
     base.Update(gameTime);  // Agent's Update();
 }
예제 #53
0
 /// <summary>
 /// Check to see if a node is already in a set
 /// based on their position NOT distance
 /// </summary>
 /// <param name="current">a NavNode</param>
 /// <param name="set">the current set (either closeSet or openSet)</param>
 /// <returns>true if it's in, false otherwise</returns>
 private bool IsNodeIn(NavNode current, PriorityQueue<NavNode> set)
 {
     List<NavNode> nodes = set.GetList();
     foreach (NavNode n in nodes) {
         if (n.Translation.X == current.Translation.X && n.Translation.Z == current.Translation.Z)
             return true;
     }
     return false;
 }
예제 #54
0
 /// <summary>
 /// Procedurally make a path for NPAgent to traverse
 /// </summary>
 /// <returns></returns>
 private List<NavNode> makePath()
 {
     List<NavNode> aPath = new List<NavNode>();
     int spacing = stage.Spacing;
     // make a simple path, show how to set the type of the NavNode outside of construction.
     NavNode n;
     n = new NavNode(new Vector3(505 * spacing, stage.Terrain.surfaceHeight(505, 505), 505 * spacing));
     n.Navigatable = NavNode.NavNodeEnum.PATH;
     aPath.Add(n);
     n = new NavNode(new Vector3(500 * spacing, stage.Terrain.surfaceHeight(500, 500), 500 * spacing));
     n.Navigatable = NavNode.NavNodeEnum.VERTEX;
     aPath.Add(n);
     aPath.Add(new NavNode(new Vector3(495 * spacing, stage.Terrain.surfaceHeight(495, 495), 495 * spacing),
              NavNode.NavNodeEnum.WAYPOINT));
     aPath.Add(new NavNode(new Vector3(495 * spacing, stage.Terrain.surfaceHeight(495, 505), 505 * spacing),
              NavNode.NavNodeEnum.WAYPOINT));
     // /* comment out rest of path to shorten for tests of NavNode.PathType values
     aPath.Add(new NavNode(new Vector3(100 * spacing, stage.Terrain.surfaceHeight(100, 500), 500 * spacing),
              NavNode.NavNodeEnum.WAYPOINT));
     aPath.Add(new NavNode(new Vector3(100 * spacing, stage.Terrain.surfaceHeight(100, 100), 100 * spacing),
              NavNode.NavNodeEnum.WAYPOINT));
     aPath.Add(new NavNode(new Vector3(500 * spacing, stage.Terrain.surfaceHeight(500, 100), 100 * spacing),
              NavNode.NavNodeEnum.WAYPOINT));
     n = new NavNode(new Vector3(500 * spacing, stage.Terrain.surfaceHeight(500, 495), 495 * spacing));
     n.Navigatable = NavNode.NavNodeEnum.A_STAR;
     aPath.Add(n);
     aPath.Add(new NavNode(new Vector3(495 * spacing, stage.Terrain.surfaceHeight(495, 105), 105 * spacing),
              NavNode.NavNodeEnum.WAYPOINT));
     aPath.Add(new NavNode(new Vector3(105 * spacing, stage.Terrain.surfaceHeight(105, 105), 105 * spacing),
              NavNode.NavNodeEnum.WAYPOINT));
     aPath.Add(new NavNode(new Vector3(105 * spacing, stage.Terrain.surfaceHeight(105, 495), 495 * spacing),
              NavNode.NavNodeEnum.WAYPOINT));
     // */ shorter path tests
     return (aPath);
 }
예제 #55
0
        private void Move()
        {
            // update mode for each move
            if (mode == ModeEnum.EXPLORING)
                npAgentGameMode = Stage.GameMode.NP_AGENT_EXPLORING;
            else if (mode == ModeEnum.TREASURE_HUNTING)
                npAgentGameMode = Stage.GameMode.NP_AGENT_TREASURE_HUNTING;

            if (!flagSignal) {
                AddPathToExploreQueue();
                flagSignal = true;
            }

            displayAgentInfo();

            // see if at or close to nextGoal, distance measured in the flat XZ plane
            float distance = Vector3.Distance(
               new Vector3(nextGoal.Translation.X, 0, nextGoal.Translation.Z),
               new Vector3(agentObject.Translation.X, 0, agentObject.Translation.Z));

            if (distance <= snapDistance) {
                stage.SetInfo(17, string.Format("distance to goal = {0,5:f2}", distance));

                // snap to nextGoal and orient toward the new nextGoal
                nextGoal = currentPath.NextNode;
                agentObject.TurnToFace(nextGoal.Translation);

                /*
                 * Here we have two options when the current path is done
                 *      if npAgent is in TREASURE_HUNTING mode
                 *      if npAgent is in EXPLORING mode
                 */
                if (currentPath.Done) {
                    Debug.WriteLine("Path traversal is done.");
                    if (mode == ModeEnum.TREASURE_HUNTING) {
                        HandleTreasureMode();
                    }
                    else if (mode == ModeEnum.EXPLORING) {
                        HandleExploringMode();
                    }
                }
                else {
                    turnCount++;
                    // stage.SetInfo(18, string.Format("turnToFace count = {0}", turnCount));
                }
            }
        }
예제 #56
0
 void Start()
 {
     for (int i = 0; i < kids.Count; i++)
     {
       kids[i].Group = this;
     }
     Destination = destination;
     NextNode = nextNode;
 }
 public NodeUI(NavNode node)
 {
     Node = node;
     Circle = new HighlightCircle(node.Position);
 }
예제 #58
0
        /// <summary>
        /// Create a NPC. 
        /// AGXNASK distribution has npAgent move following a Path.
        /// </summary>
        /// <param name="theStage"> the world</param>
        /// <param name="label"> name of </param>
        /// <param name="pos"> initial position </param>
        /// <param name="orientAxis"> initial rotation axis</param>
        /// <param name="radians"> initial rotation</param>
        /// <param name="meshFile"> Direct X *.x Model in Contents directory </param>
        public NPAgent(Stage theStage, string label, Vector3 pos, Vector3 orientAxis, float radians, string meshFile)
            : base(theStage, label, pos, orientAxis, radians, meshFile)
        {
            IsCollidable = true;

            first.Name = "npFirst";
            follow.Name = "npFollow";
            above.Name = "npAbove";

            // initialize all treasures
            InitializeMarkTreasures();

            // initialize treasure path queue
            treasurePathQueue = new Queue<Path>();
            // initialize exploring path queue
            explorePathQueue = new Queue<Path>();

            // add all predefined path to explore path queue
            // AddPathToExploreQueue();

            Path initialPath = new Path(stage, MakeExploringPaths(), Path.PathType.SINGLE, true);

             // set it to current path
            currentPath = initialPath;

            // set the mode
            mode = ModeEnum.EXPLORING;
            npAgentGameMode = Stage.GameMode.NP_AGENT_EXPLORING;

            stage.Components.Add(currentPath);
            nextGoal = currentPath.NextNode;
            agentObject.TurnToFace(nextGoal.Translation);
        }
예제 #59
0
	// Adds a NavNode the NavArea nodes list
	public void AddNode(NavNode nodeToAdd){
		m_areaNodes.Add(nodeToAdd);
	}
예제 #60
0
 public List<NavNode> searchForPath(NavNode para_sourceNode, NavNode para_destNode, HashSet<int> para_untraversibleTypes)
 {
     NavGraph thisObj = this;
     List<int> pathIDs = navAlgorithm.searchForPath(ref thisObj,para_sourceNode,para_destNode,para_untraversibleTypes);
     if(pathIDs == null)
     {
         return null;
     }
     else
     {
         List<NavNode> reqData = convertIDListToNodeList(pathIDs);
         return reqData;
     }
 }