{ 495, 480 } }; // loop return /// <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)); }
public void treasureDetection() { Object3D tempTreasure = findClosestTreasure(this.stage.getTreasure); float distance = Vector3.Distance(tempTreasure.Translation, this.agentObject.Translation); if (distance < (tempTreasure.ObjectBoundingSphereRadius + detectionRadius)) { NavNode closestNode = this.stage.graph.findClosestNavNodeInGraph(this.agentObject.Translation); NavNode treasureNode = this.stage.graph.getNavNode((int)tempTreasure.Translation.X, (int)tempTreasure.Translation.Z); Path aStarPath = new Path(this.stage, this.stage.graph.aStarPathFinding(closestNode, treasureNode), Path.PathType.SINGLE); path = aStarPath; } }
// Get or Set a NavNode in the graph public NavNode this[int x, int z] { get { NavNode node = null; try { node = graph[stringKey(x, z)]; return(node); } catch (KeyNotFoundException) { return(node); } } set { graph[stringKey(x, z)] = value; } }
{ 495, 480 } }; // loop return /// <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, Treasure treasure) // Edited by David Kopp : 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)); treasureMode = false; // Treasure mode initilized to false - added by David Kopp score = 0; // Score of NPAgent initialized to 0 - added by David Kopp isCollidable = true; aStarDone = false; }
/// <summary> /// Handle player input that affects the player. /// See Stage.Update(...) for handling user input that affects /// how the stage is rendered. /// First check if gamepad is connected, if true use gamepad /// otherwise assume and use keyboard. /// (Added by David Kopp) If the Player / Evader gets within /// 300 pixels of a treasure that is not tagged then it will be /// tagged and their score will increase by 1. If there is no /// untagged treasure then treasureMode = false. /// </summary> /// <param name="gameTime"></param> public override void Update(GameTime gameTime) { KeyboardState keyboardState = Keyboard.GetState(); if (keyboardState.IsKeyDown(Keys.R) && !oldKeyboardState.IsKeyDown(Keys.R)) { agentObject.Orientation = initialOrientation; } // allow more than one keyboardState to be pressed if (keyboardState.IsKeyDown(Keys.Up)) { agentObject.Step++; } if (keyboardState.IsKeyDown(Keys.Down)) { agentObject.Step--; } if (keyboardState.IsKeyDown(Keys.Left)) { rotate++; } if (keyboardState.IsKeyDown(Keys.Right)) { rotate--; } oldKeyboardState = keyboardState; // Update saved state. agentObject.Yaw = rotate * angle; // Player / Evader tags closest Treasure if it is untagged - added by David Kopp NavNode temp = stage.Treasure.getTreasure(agentObject.Translation); if (temp != null && Vector3.Distance((temp.Translation), agentObject.Translation) < 75 && treasureMode) { stage.Treasure.tagTreasure(temp.Translation); // Player tags the treasure - by David Kopp // treasureMode = false; // Uncomment to have the player play the treasure game - by David Kopp score++; // Increase Player / Evader's score by 1 - by David Kopp } else if (temp == null) // All treasures are tagged - by David Kopp { treasureMode = false; } base.Update(gameTime); rotate = agentObject.Step = 0; }
// finds the closest NavNode from the given location. public NavNode findClosestNavNodeInGraph(Vector3 location) { NavNode closestNode = new NavNode(new Vector3(0)); float shortestDistance = 100000.0f; float distance = 0.0f; SortedDictionary <String, NavNode> sortedList = new SortedDictionary <string, NavNode>(graph); foreach (KeyValuePair <String, NavNode> node in sortedList) { distance = Vector3.Distance(node.Value.Translation, location); if (distance < shortestDistance) { shortestDistance = distance; closestNode = node.Value; } } return(closestNode); }
// A * public List <NavNode> aStarPathFinding(NavNode source, NavNode destination) { open = new List <NavNode>(); closed = new List <NavNode>(); path = new List <NavNode>(); NavNode current = source; current.Cost = 0; open.Add(current); open.Sort(delegate(NavNode n1, NavNode n2) { return(n1.Cost.CompareTo(n2.Cost)); }); while (open.Count != 0) { current = open.First <NavNode>(); open.Remove(open.First <NavNode>()); if (current.Translation == destination.Translation) { break; } closed.Add(current); current.Navigatable = NavNode.NavNodeEnum.CLOSED; foreach (NavNode adjacent in current.Adjacent) { if (!open.Contains(adjacent) && !closed.Contains(adjacent)) { adjacent.PredecessorNode = current; adjacent.DistanceFromSource = current.DistanceFromSource + Vector3.Distance(current.Translation, adjacent.Translation); adjacent.DistanceToGoal = Vector3.Distance(current.Translation, adjacent.Translation) + Vector3.Distance(adjacent.Translation, destination.Translation); adjacent.Cost = adjacent.DistanceFromSource + adjacent.DistanceToGoal; open.Add(adjacent); adjacent.Navigatable = NavNode.NavNodeEnum.OPEN; } } open.Sort(delegate(NavNode n1, NavNode n2) { return(n1.Cost.CompareTo(n2.Cost)); }); } while (Vector3.Distance(current.Translation, source.Translation) != 0.0) { current.Navigatable = NavNode.NavNodeEnum.PATH; path.Add(current); current = current.PredecessorNode; } aStarCompleted = true; path.Reverse(); return(path); }
/// <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. (Added by David Kopp) If treasure mode is enabled the nextGoal will be /// the closest treasure to the NPAgent. After the NPAgent tags the treasure nextGoal will be the last NavNode the /// NPAgent was going to before entering treasure mode. /// </summary> public override void Update(GameTime gameTime) { // Check for if in treasureMode and nextGoal is not a treasure, and the game is not over - by David Kopp if (treasureMode & !stage.Treasure.isTreasure(nextGoal.Translation) & !stage.Treasure.GameOver) { NavNode temp = stage.Treasure.getTreasure(agentObject.Translation); // Location of closest treasure - by David Kopp if (temp != null && !stage.Treasure.isTagged(temp.Translation)) // If there is a treasure and the treasure is untagged - by David Kopp { nextGoalTemp = nextGoal; // Hold the NavNode the Agent was going to before Treasure mode is enabled - by David Kopp nextGoal = temp; } } else if (treasureMode && stage.Treasure.isTreasure(nextGoal.Translation)) // Check if treasure mode is enabled and NPAgent is going to a treasure - by David Kopp { if (stage.Treasure.GameOver) // If the game is over in route to a treasure, that was just tagged, then the NPAgent goes back to following the static path - by David Kopp { nextGoal = nextGoalTemp; } else if (!stage.Treasure.GameOver && stage.Treasure.isTagged(nextGoal.Translation)) // If the game is not over and in route the treasure gets tagged - by David Kopp { NavNode switchTemp = stage.Treasure.getTreasure(agentObject.Translation); // Switch nextGoal with an untagged treasure - by David Kopp if (switchTemp != null) // If the game is not over and in route to a treasure that just got tagged, then NPAgent will goto the next closest untagged treasure - by David Kopp { nextGoal = switchTemp; } else // If the game is not over in route to a treasure and the treasure, which was the last untagged, gets tagged. NPAgent goes back to the static path and disable treasure mode - by David Kopp { nextGoal = nextGoalTemp; treasureMode = !treasureMode; } } } else if (!treasureMode && stage.Treasure.isTreasure(nextGoal.Translation)) // If treasure mode is disabled and the NPAgent was heading for a Treasure (Not implemented) - by David Kopp { nextGoal = nextGoalTemp; } agentObject.turnToFace(nextGoal.Translation); // adjust to face nextGoal every move // See if at or close to nextGoal, distance measured in 2D xz plane float 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 && !stage.Treasure.isTreasure(nextGoal.Translation)) // Added if the nextGoal is not a treasure - by David Kopp // snap to nextGoal and orient toward the new nextGoal { nextGoal = path.NextNode; // agentObject.turnToFace(nextGoal.Translation); } else if (distance <= snapDistance && stage.Treasure.isTreasure(nextGoal.Translation)) // If the NPAgent approaches a treasure and tags it - Added by David Kopp { stage.Treasure.tagTreasure(nextGoal.Translation); // Tag the treasure - by David Kopp nextGoal = nextGoalTemp; // NPAgent head back to last NavNode before treasure mode was enabled -by David Kopp treasureMode = false; // Disable treasure mode - by David Kopp score++; // Increase NPAgent's treasure score by 1 - by David Kopp } base.Update(gameTime); // Agent's Update(); }
/// <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. (Added by David Kopp) If treasure mode is enabled the nextGoal will be /// the closest treasure to the NPAgent. After the NPAgent tags the treasure nextGoal will be the last NavNode the /// NPAgent was going to before entering treasure mode. /// </summary> public override void Update(GameTime gameTime) { // Treasure scan - By David Kopp NavNode scan = stage.Treasure.getTreasure(agentObject.Translation); if (!treasureMode && stage.Treasure.distanceToTreasure(agentObject.Translation, scan.Translation) <= 4000.0f && !stage.Treasure.GameOver) { nextGoalTemp = nextGoal; scanTemp = scan; treasureMode = true; treasurePathing = true; } // Start aStar and fix astar algorithm if (!aStarDone && treasureMode && treasurePathing && !stage.Treasure.GameOver) { NavNode closestGraphNode = graph.nearestGraphPoint(agentObject.Translation); List <NavNode> aStarPath = graph.aStarAlgorithm(closestGraphNode, scan); Path treasureHuntingPath = new Path(stage, aStarPath, Path.PathType.LOOP); nextGoal = treasureHuntingPath.NextNode; aStarDone = true; } // This needs to check that the treasure is still not tagged and keep folowing astar path. if (aStarDone && !stage.Treasure.isTagged(scanTemp.Translation)) { } // // Check for if in treasureMode and nextGoal is not a treasure, and the game is not over - by David Kopp // if (treasureMode & !stage.Treasure.isTreasure (nextGoal.Translation) & !stage.Treasure.GameOver) { // NavNode temp = stage.Treasure.getTreasure (agentObject.Translation); // Location of closest treasure - by David Kopp // if (temp != null && !stage.Treasure.isTagged (temp.Translation)) { // If there is a treasure and the treasure is untagged - by David Kopp // nextGoalTemp = nextGoal; // Hold the NavNode the Agent was going to before Treasure mode is enabled - by David Kopp // nextGoal = temp; // } // } else if (treasureMode && stage.Treasure.isTreasure (nextGoal.Translation)) { // Check if treasure mode is enabled and NPAgent is going to a treasure - by David Kopp // if (stage.Treasure.GameOver) { // If the game is over in route to a treasure, that was just tagged, then the NPAgent goes back to following the static path - by David Kopp // nextGoal = nextGoalTemp; // } else if (!stage.Treasure.GameOver && stage.Treasure.isTagged (nextGoal.Translation)) { // If the game is not over and in route the treasure gets tagged - by David Kopp // NavNode switchTemp = stage.Treasure.getTreasure (agentObject.Translation); // Switch nextGoal with an untagged treasure - by David Kopp // if (switchTemp != null) { // If the game is not over and in route to a treasure that just got tagged, then NPAgent will goto the next closest untagged treasure - by David Kopp // nextGoal = switchTemp; // } else { // If the game is not over in route to a treasure and the treasure, which was the last untagged, gets tagged. NPAgent goes back to the static path and disable treasure mode - by David Kopp // nextGoal = nextGoalTemp; // treasureMode = !treasureMode; // } // } // } else if (!treasureMode && stage.Treasure.isTreasure (nextGoal.Translation)) { // If treasure mode is disabled and the NPAgent was heading for a Treasure (Not implemented) - by David Kopp // nextGoal = nextGoalTemp; // } else if (!treasureMode && !stage.Treasure.GameOver) { // new addition // treasureMode = true; // NavNode scan = stage.Treasure.getTreasure; // if (!aStarDone && stage.Treasure.distanceToTreasure(agentObject.Translation, scan.Translation) <= 4000.0f) { // nextGoalTemp = nextGoal; // NavNode findClosestNodeToTreasurePath = 0; // // } // } //agentObject.turnToFace(nextGoal.Translation); // adjust to face nextGoal every move // See if at or close to nextGoal, distance measured in 2D xz plane float 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)); // This section controls how the npagent goes back to the path after he snaps to the treasure. This section is not // complete and needs to have clearer conditions. many of these are still from project 1. if (distance <= snapDistance && !stage.Treasure.isTreasure(nextGoal.Translation)) // Added if the nextGoal is not a treasure - by David Kopp // snap to nextGoal and orient toward the new nextGoal { nextGoal = path.NextNode; // agentObject.turnToFace(nextGoal.Translation); } else if (distance <= snapDistance && stage.Treasure.isTreasure(nextGoal.Translation)) // If the NPAgent approaches a treasure and tags it - Added by David Kopp { stage.Treasure.tagTreasure(nextGoal.Translation); // Tag the treasure - by David Kopp //nextGoal = nextGoalTemp; // NPAgent head back to last NavNode before treasure mode was enabled -by David Kopp //treasureMode = false; // Disable treasure mode - by David Kopp score++; // Increase NPAgent's treasure score by 1 - by David Kopp } base.Update(gameTime); // Agent's Update(); }
/// <summary> /// Added a treasure to NPA's goal /// </summary> /// <param name="newTreasureNode">treasure</param> public void newTreasureGoal(NavNode newTreasureNode) { nextGoal = newTreasureNode; treasureTarget = newTreasureNode; }