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); } }
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); } }
/// <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); }
/// <summary> /// Create exploring path using A* algorithm /// to avoid collision /// </summary> private void AddPathToExploreQueue() { /** * We move as follows * + path: * s -> x1 -> x2 -> x3 -> x4 -> ... * * + direction: * right -> down -> right -> up -> right -> down .... * * + cover an rectangle area of 52 * spacing since the distance * of seeing is 4000 pixles = 26 * 150 * * ================= * = Map 512 x 512 = * ================= * * 100 200 300 400 500 * ------------|------------|------------|------------|------------| * | | * | s ------> x1 x4 -----------> | * | | ^ . | * | | | . | * 100 - | | . | * | | | . | * | | | | * | | | | * | | | | * 200 - | | | * | | | | * | | | | * | | | | * | | | | * 300 - | | | * | | | | * | | | | * | | | | * | | | | * 400 - | | | * | | | | * | V | | * | x2 ----------> x3 | * | | * 500 ----------------------------------------------------------------- * */ Vector3 start = new Vector3(0, 0, 0); Vector3 goal = new Vector3(0, 0, 0); Vector3 x0 = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 78), 78 * stage.Spacing); Vector3 x1 = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 130), 130 * stage.Spacing); Vector3 x2 = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 182), 182 * stage.Spacing); Vector3 x3 = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 234), 234 * stage.Spacing); Vector3 x4 = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 286), 286 * stage.Spacing); Vector3 x5 = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 338), 338 * stage.Spacing); Vector3 x6 = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 390), 390 * stage.Spacing); Vector3 x7 = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 442), 442 * stage.Spacing); Vector3 x8 = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 494), 494 * stage.Spacing); Vector3 z0 = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 26), 26 * stage.Spacing); Vector3 z1 = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 78), 78 * stage.Spacing); Vector3 z2 = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 130), 130 * stage.Spacing); Vector3 z3 = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 182), 182 * stage.Spacing); Vector3 z4 = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 234), 234 * stage.Spacing); Vector3 z5 = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 286), 286 * stage.Spacing); Vector3 z6 = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 338), 338 * stage.Spacing); Vector3 z7 = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 390), 390 * stage.Spacing); Vector3 z8 = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 442), 442 * stage.Spacing); Vector3 z9 = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 494), 494 * stage.Spacing); /* * Debugging only to show path pattern */ bool ifDebug = false; bool displayPath = ifDebug; // right start = z0; goal = z1; Path p1 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) { stage.Components.Add(p1); } explorePathQueue.Enqueue(p1); // down start = z1; goal = x0; Path p2 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) { stage.Components.Add(p2); } explorePathQueue.Enqueue(p2); // right start = x0; goal = x1; Path p3 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) { stage.Components.Add(p3); } explorePathQueue.Enqueue(p3); // up start = x1; goal = z2; Path p4 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) { stage.Components.Add(p4); } explorePathQueue.Enqueue(p4); // right start = z2; goal = z3; Path p5 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) { stage.Components.Add(p5); } explorePathQueue.Enqueue(p5); // down start = z3; goal = x2; Path p6 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) { stage.Components.Add(p6); } explorePathQueue.Enqueue(p6); // right start = x2; goal = x3; Path p7 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) { stage.Components.Add(p7); } explorePathQueue.Enqueue(p7); // up start = x3; goal = z4; Path p8 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) { stage.Components.Add(p8); } explorePathQueue.Enqueue(p8); // right start = z4; goal = z5; Path p9 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) { stage.Components.Add(p9); } explorePathQueue.Enqueue(p9); // down start = z5; goal = x4; Path p10 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) { stage.Components.Add(p10); } explorePathQueue.Enqueue(p10); // right start = x4; goal = x5; Path p11 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) stage.Components.Add(p11); explorePathQueue.Enqueue(p11); // up start = x5; goal = z6; Path p12 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) stage.Components.Add(p12); explorePathQueue.Enqueue(p12); // right start = z6; goal = z7; Path p13 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) stage.Components.Add(p13); explorePathQueue.Enqueue(p13); // down start = z7; goal = x6; Path p14 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) stage.Components.Add(p14); explorePathQueue.Enqueue(p14); // right start = x6; goal = x7; Path p15 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) stage.Components.Add(p15); explorePathQueue.Enqueue(p15); // up start = x7; goal = z8; Path p16 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) stage.Components.Add(p16); explorePathQueue.Enqueue(p16); // right start = z8; goal = z9; Path p17 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) stage.Components.Add(p17); explorePathQueue.Enqueue(p17); // down start = z9; goal = x8; Path p18 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath); if (ifDebug) stage.Components.Add(p18); explorePathQueue.Enqueue(p18); }
/// <summary> /// Build an A* path to treasure /// and add it to the treasure path queue /// </summary> /// <param name="idx">index of treasure</param> private void AddNewTreasurePath(int idx) { // build A* path to goal int startX = (int)(agentObject.Translation.X / 150); int startZ = (int)(agentObject.Translation.Z / 150); int goalX = (int)(stage.Treasures[idx].Translation.X / 150); int goalZ = (int)(stage.Treasures[idx].Translation.Z / 150); Vector3 start = new Vector3(startX * stage.Terrain.Spacing, stage.Terrain.SurfaceHeight(startX, startZ), startZ * stage.Terrain.Spacing); Vector3 goal = new Vector3(goalX * stage.Terrain.Spacing, stage.Terrain.SurfaceHeight(goalX, goalZ), goalZ * stage.Terrain.Spacing); // create A* path forward to treasure Path forwardPath = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.A_STAR), Path.PathType.SINGLE, true); // add this path to queue treasurePathQueue.Enqueue(forwardPath); // create A* path backward to previous position if (goalX == LocationConstant.TREASURE_1_X && goalZ == LocationConstant.TREASURE_1_Z) { Path backwardPath = new Path(stage, MakeAStarPath(goal, start, NavNode.NavNodeEnum.PATH), Path.PathType.SINGLE, true); // add this path to queue treasurePathQueue.Enqueue(backwardPath); } }
/// <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); }