public bool Intersects(BaseObject o) { float angle = (float)Math.Atan2(o.CenterPoint.Y - CenterPoint.Y, o.CenterPoint.X - CenterPoint.X); Vector2 point = CenterPoint + new Vector2(Radius * (float)Math.Cos(angle), Radius * (float)Math.Sin(angle)); //return o.Touches(point); return o.Touches(point) || Vector2.Distance(CenterPoint, o.CenterPoint) < Radius;// || //((Math.Abs(centerPoint.X - o.X) < radius || Math.Abs(centerPoint.X - (o.X + o.Width)) < radius) && //(Math.Abs(centerPoint.Y - o.Y) < radius || Math.Abs(centerPoint.Y - (o.Y + o.Height)) < radius)); }
public bool IsNearRotated(BaseObject r, float factor) { Rectangle inflatedRectangle = new Rectangle(X, Y, Width, Height); inflatedRectangle.Inflate((int)(Width * factor), (int)(Height * factor)); return r.Intersects(inflatedRectangle); }
public virtual bool Intersects(BaseObject o) { return Rectangle.Intersects(o.Rectangle); }
public void AddPotentialCollision(BaseObject o) { //lock (PotentialCollisions) //{ potentialCollisions.Add(o); //} }
public ScheduledStructureTargetedCommand(float scheduledTime, Structure structure, CommandButtonType commandType, BaseObject target, Vector2 point, bool queued) : base(scheduledTime, structure, commandType) { Target = target; Point = point; Queued = queued; }
public ScheduledUnitTargetedCommand(float scheduledTime, UnitCommand unitCommand, BaseObject target, bool queued) : base(scheduledTime, unitCommand, queued) { Target = target; }
public Rts(EventHandler callback, Lidgren.Network.NetPeer netpeer, short myTeam) : base(callback) { netPeer = netpeer; iAmServer = netPeer is NetServer; Game1.Game.DebugMonitor.Position = Direction.NorthEast; //Game1.Game.Graphics.SynchronizeWithVerticalRetrace = false; //Game1.Game.IsFixedTimeStep = false; //Game1.Game.Graphics.ApplyChanges(); //GameTimer.Restart(); //map = new Map(@"Content/map1.muh"); map = new Map("C:\\rts maps\\map2.muh"); pathFinder = new PathFinder(map); map.InstantiateMapResources(); //Player.Me.Team = myTeam; Player.Me = Player.Players[myTeam]; actualMapWidth = map.Width * map.TileSize; actualMapHeight = map.Height * map.TileSize; Unit.UnitCollisionSweeper.Thread.Suspend(); Unit.UnitCollisionSweeper.Thread.Resume(); Rts.pathFinder.ResumeThread(); uiViewport = GraphicsDevice.Viewport; worldViewport = GraphicsDevice.Viewport; minimapViewport = new Viewport(minimapBorderSize, uiViewport.Height - minimapSize - minimapBorderSize, minimapSize, minimapSize); //minimapViewport = new Viewport(0, 0, minimapSize, minimapSize); worldViewport.Height -= (minimapSize + minimapBorderSize * 2); GraphicsDevice.Viewport = worldViewport; camera = new Camera(); camera.Pos = new Vector2(worldViewport.Width / 2, worldViewport.Height / 2); button1 = new BaseObject(new Rectangle(10, 25, 25, 25)); button2 = new BaseObject(new Rectangle(10, 52, 25, 25)); button3 = new BaseObject(new Rectangle(10, 79, 25, 25)); button4 = new BaseObject(new Rectangle(10, 106, 25, 25)); button5 = new BaseObject(new Rectangle(10, 133, 25, 25)); if (!contentLoaded) { pauseFont = Content.Load<SpriteFont>("spritefonts/pausefont"); fpsFont = Content.Load<SpriteFont>("spritefonts/fpsfont"); unitInfoUnitNameFont = Content.Load<SpriteFont>("spritefonts/UnitInfoUnitNameFont"); unitInfoHpFont = Content.Load<SpriteFont>("spritefonts/UnitInfoHpFont"); unitInfoKillCountFont = Content.Load<SpriteFont>("spritefonts/UnitInfoKillCountFont"); resourceCountFont = Content.Load<SpriteFont>("spritefonts/ResourceCountFont"); bigFont = Content.Load<SpriteFont>("spritefonts/BigMessage"); //brownGuyTexture = Content.Load<Texture2D>("unit textures/browncircleguy"); //brownGuySelectingTexture = Content.Load<Texture2D>("unit textures/browncircleguyselected2"); //brownGuySelectedTexture = Content.Load<Texture2D>("unit textures/browncircleguyselecting2"); greenTeamIndicatorTexture = Content.Load<Texture2D>("unit textures/green team indicator"); redTeamIndicatorTexture = Content.Load<Texture2D>("unit textures/red team indicator"); buttonTexture = Content.Load<Texture2D>("titlebutton1"); moveCommandShrinkerTexture = Content.Load<Texture2D>("greencircle2"); attackMoveCommandShrinkerTexture = Content.Load<Texture2D>("redcircle2"); //normalCursorTexture = Content.Load<Texture2D>("greencursor2"); //attackCommandCursorTexture = Content.Load<Texture2D>("crosshair"); normalCursor = Util.LoadCustomCursor(@"Content/cursors/SC2-cursor.cur"); attackCursor = Util.LoadCustomCursor(@"Content/cursors/SC2-target-none.cur"); boulder1Texture = Content.Load<Texture2D>("boulder1"); tree1Texture = Content.Load<Texture2D>("tree2"); rallyFlagTexture = Content.Load<Texture2D>("redflag"); redCircleTexture = Content.Load<Texture2D>("redcircle"); transparentTexture = Content.Load<Texture2D>("transparent"); transparentGrayTexture = Content.Load<Texture2D>("transparentgray"); transparentBlackTexture = Content.Load<Texture2D>("transparentblack"); whiteBoxTexture = Content.Load<Texture2D>("whitebox"); cogWheelTexture = Content.Load<Texture2D>("cogwheel"); rtsMusic = Content.Load<Song>("music/58 - Weapons Factory"); errorSoundEffect = Content.Load<SoundEffect>("sounds/Error"); //Unit.BulletTexture = Content.Load<Texture2D>("bullet"); Unit.Explosion1Textures = Util.SplitTexture(Content.Load<Texture2D>("explosionsheet1"), 45, 45); Structure.Explosion1Textures = Util.SplitTexture(Content.Load<Texture2D>("explosionsheet1"), 45, 45); contentLoaded = true; } winForm = (Form)Form.FromHandle(Game1.Game.Window.Handle); //Cursor.Clip = new System.Drawing.Rectangle(winForm.Location, winForm.Size); winForm.Cursor = normalCursor; initializeMapTexture(); initializeCommandCardArea(); initializeSelectionInfoArea(); line.Alpha = .75f; VisionUpdater = new VisionUpdater(map, Rts.pathFinder, Player.Me.Team); SelectBox.InitializeSelectBoxLine(GraphicsDevice, Color.Green); Initializeline(GraphicsDevice, Color.Yellow); minimapScreenIndicatorBoxLine = new PrimitiveLine(GraphicsDevice, 1); minimapScreenIndicatorBoxLine.Colour = Color.White; for (int i = 0; i < HotkeyGroups.Length; i++) HotkeyGroups[i] = new List<RtsObject>(); MediaPlayer.Play(rtsMusic); MediaPlayer.Volume = MusicVolume; MediaPlayer.IsRepeating = true; /*new TownHall(map.StartingPoints[myTeam], myTeam); camera.Pos = new Vector2(map.StartingPoints[myTeam].X * map.TileSize, map.StartingPoints[myTeam].Y * map.TileSize); Player.Me.MaxSupply += StructureType.TownHall.Supply;*/ initializeStartingPoints(); //new Barracks(new Point(10, 14), 2); //new Roks(new Point(3, 3)); //new Roks(new Point(3, 30)); Player.Me.Roks = 25; clampCameraToMap(); initialHandShake(); }
void initializeMapTexture() { // set minimap fields and create rectangle object minimapPosX = minimapBorderSize; minimapPosY = uiViewport.Height - minimapSize - minimapBorderSize; //minimapPosX = 0; //minimapPosY = 0; minimapToMapRatioX = (float)minimapSize / (map.Width * map.TileSize); minimapToMapRatioY = (float)minimapSize / (map.Height * map.TileSize); minimapToScreenRatioX = (float)minimapSize / worldViewport.Width; minimapToScreenRatioY = (float)minimapSize / worldViewport.Height; minimap = new Rectangle(minimapPosX, minimapPosY, minimapSize, minimapSize); //minimap = new Rectangle(0, 0, minimapSize, minimapSize); minimapScreenIndicatorBox = new BaseObject(new Rectangle(0, 0, (int)(worldViewport.Width * minimapToMapRatioX), (int)(worldViewport.Height * minimapToMapRatioY))); //fullMapTexture = new Texture2D(GraphicsDevice, map.Width * Map.TILESIZE, map.Height * Map.TILESIZE); //fullMapTexture = new RenderTarget2D(GraphicsDevice, map.Width * Map.TILESIZE, map.Height * Map.TILESIZE); // create full map texture from map tiles RenderTarget2D renderTarget = new RenderTarget2D(GraphicsDevice, map.Width * map.TileSize, map.Height * map.TileSize); GraphicsDevice.SetRenderTarget(renderTarget); GraphicsDevice.Clear(Color.Gray); SpriteBatch spriteBatch = new SpriteBatch(GraphicsDevice); spriteBatch.Begin(); for (int x = 0; x < map.Width; x++) { for (int y = 0; y < map.Height; y++) { MapTile tile = map.Tiles[y, x]; if (tile.Type == 0) spriteBatch.Draw(ColorTexture.Gray, tile.Rectangle, Color.White); else if (tile.Type == 1) spriteBatch.Draw(boulder1Texture, tile.Rectangle, Color.White); else if (tile.Type == 2) spriteBatch.Draw(tree1Texture, tile.Rectangle, Color.White); } } spriteBatch.End(); GraphicsDevice.SetRenderTarget(null); //fullMapTexture = (Texture2D)renderTarget; fullMapTexture = new Texture2D(GraphicsDevice, map.Width * map.TileSize, map.Height * map.TileSize); Color[] textureData = new Color[(map.Width * map.TileSize) * (map.Height * map.TileSize)]; renderTarget.GetData<Color>(textureData); fullMapTexture.SetData<Color>(textureData); //renderTarget = null; //GC.Collect(); }
private bool IsAxisCollision(BaseObject theRectangle, Vector2 aAxis) { //List<int> aRectangleAScalars = new List<int>(); aRectangleAScalars.Clear(); aRectangleAScalars.Add(GenerateScalar(theRectangle.UpperLeftCorner, aAxis)); aRectangleAScalars.Add(GenerateScalar(theRectangle.UpperRightCorner, aAxis)); aRectangleAScalars.Add(GenerateScalar(theRectangle.LowerLeftCorner, aAxis)); aRectangleAScalars.Add(GenerateScalar(theRectangle.LowerRightCorner, aAxis)); //List<int> aRectangleBScalars = new List<int>(); aRectangleBScalars.Clear(); aRectangleBScalars.Add(GenerateScalar(UpperLeftCorner, aAxis)); aRectangleBScalars.Add(GenerateScalar(UpperRightCorner, aAxis)); aRectangleBScalars.Add(GenerateScalar(LowerLeftCorner, aAxis)); aRectangleBScalars.Add(GenerateScalar(LowerRightCorner, aAxis)); int aRectangleAMinimum = aRectangleAScalars.Min(); int aRectangleAMaximum = aRectangleAScalars.Max(); int aRectangleBMinimum = aRectangleBScalars.Min(); int aRectangleBMaximum = aRectangleBScalars.Max(); if (aRectangleBMinimum <= aRectangleAMaximum && aRectangleBMaximum >= aRectangleAMaximum) { return true; } else if (aRectangleAMinimum <= aRectangleBMaximum && aRectangleAMaximum >= aRectangleBMaximum) { return true; } return false; }
public List <Vector2> FindPath(PathNode startNode, Vector2 endPoint, Unit unit, BaseObject target, bool avoidUnits) { // Only try to find a path if the start and end points are different. if (Vector2.Distance(startNode.Tile.CenterPoint, endPoint) <= Map.TileSize) { List <Vector2> list = new List <Vector2>(); list.Add(endPoint); Cleanup(); return(list); } /*int startPointY = (int)(startPoint.Y / Map.TILESIZE); * int startPointX = (int)(startPoint.X / Map.TILESIZE); * * if ((startPointY < 0 || startPointY >= Map.Height || startPointX < 0 || startPointX >= Map.Width) || (PathNodes[startPointY, startPointX] == null)) || offset = Vector2.Zero; ||else || offset = startNode.Tile.CenterPoint - startPoint;*/ Vector2 startPoint = startNode.Tile.CenterPoint; PathNode endNode = PathNodes[(int)(endPoint.Y / Map.TileSize), (int)(endPoint.X / Map.TileSize)]; currentUnit = unit; ///////////////////////////////////////////////////////////////////// // Step 1 : Clear the Open and Closed Lists and reset each node’s F // and G values in case they are still set from the last // time we tried to find a path. ///////////////////////////////////////////////////////////////////// ResetSearchNodes(); ///////////////////////////////////////////////////////////////////// // Step 2 : Set the start node’s G value to 0 and its F value to the // estimated distance between the start node and goal node // (this is where our H function comes in) and add it to the // Open List. ///////////////////////////////////////////////////////////////////// startNode.InOpenList = true; //if (!avoidUnits) //startNode.DistanceToGoal = HeuristicManhattan(startPoint, endPoint); //else startNode.DistanceToGoal = HeuristicManhattan(startPoint, endPoint); startNode.DistanceTravelled = 0; OpenList.Add(startNode); CleanupList.Add(startNode); ///////////////////////////////////////////////////////////////////// // Setp 3 : While there are still nodes to look at in the Open list : ///////////////////////////////////////////////////////////////////// while (OpenList.Count > 0) { ///////////////////////////////////////////////////////////////// // a) : Loop through the Open List and find the node that // has the smallest F value. ///////////////////////////////////////////////////////////////// PathNode currentNode = FindBestNode(); //pathCount++; ///////////////////////////////////////////////////////////////// // c) : If the Active Node is the goal node, we will // find and return the final path. ///////////////////////////////////////////////////////////////// //if (pathCount >= MaxPathSize) //{ // Cleanup(); // return FindFinalPath(startNode, currentNode, endPoint); //} if (currentNode == endNode) { // Trace our path back to the start. Cleanup(); return(FindFinalPath(startNode, currentNode, endPoint)); } ///////////////////////////////////////////////////////////////// // d) : Else, for each of the Active Node’s neighbours : ///////////////////////////////////////////////////////////////// for (int i = 0; i < currentNode.Neighbors.Count; i++) { PathNode neighbor = currentNode.Neighbors[i]; ////////////////////////////////////////////////// // i) : Make sure that the neighbouring node can // be walked across. ////////////////////////////////////////////////// if (neighbor.Blocked) { if (target == null || neighbor.Blocker != target) { continue; } } if (!neighbor.Tile.Walkable) { continue; } //if (avoidUnits && neighbor.UnitsContained.Count > 0) // continue; ////////////////////////////////////////////////// // ii) Calculate a new G value for the neighbouring node. ////////////////////////////////////////////////// float distanceTravelled; if (currentNode.IsNeighborDiagonal[i]) { if (avoidUnits) { distanceTravelled = currentNode.DistanceTravelled + 14; } else { continue; } } else { distanceTravelled = currentNode.DistanceTravelled + 10; } // An estimate of the distance from this node to the end node. float heuristic; if (!avoidUnits) { heuristic = HeuristicManhattan(neighbor.Tile.CenterPoint, endPoint); } else { if (currentNode.IsNeighborDiagonal[i]) { heuristic = HeuristicManhattan(neighbor.Tile.CenterPoint, endPoint) + (neighbor.UnitsContained.Count * 14); } else { heuristic = HeuristicManhattan(neighbor.Tile.CenterPoint, endPoint) + (neighbor.UnitsContained.Count * 10); } } ////////////////////////////////////////////////// // iii) If the neighbouring node is not in either the Open // List or the Closed List : ////////////////////////////////////////////////// if (!neighbor.InOpenList && !neighbor.InClosedList) { // (1) Set the neighbouring node’s G value to the G value // we just calculated. if (avoidUnits) { if (currentNode.IsNeighborDiagonal[i]) { neighbor.DistanceTravelled = distanceTravelled + (neighbor.UnitsContained.Count * 1400000); } else { neighbor.DistanceTravelled = distanceTravelled + (neighbor.UnitsContained.Count * 1000000); } } else { neighbor.DistanceTravelled = distanceTravelled; } // (2) Set the neighbouring node’s F value to the new G value + // the estimated distance between the neighbouring node and // goal node. // normal A* neighbor.DistanceToGoal = neighbor.DistanceTravelled + heuristic; // best-first //neighbor.DistanceToGoal = heuristic; // (3) Set the neighbouring node’s Parent property to point at the Active // Node. neighbor.Parent = currentNode; // (4) Add the neighbouring node to the Open List. neighbor.InOpenList = true; OpenList.Add(neighbor); CleanupList.Add(neighbor); } ////////////////////////////////////////////////// // iv) Else if the neighbouring node is in either the Open // List or the Closed List : ////////////////////////////////////////////////// else if (neighbor.InOpenList || neighbor.InClosedList) { // (1) If our new G value is less than the neighbouring // node’s G value, we basically do exactly the same // steps as if the nodes are not in the Open and // Closed Lists except we do not need to add this node // the Open List again. if (neighbor.DistanceTravelled > distanceTravelled) { neighbor.DistanceTravelled = distanceTravelled; neighbor.DistanceToGoal = distanceTravelled + heuristic; //neighbor.DistanceToGoal = heuristic; neighbor.Parent = currentNode; } } } ///////////////////////////////////////////////////////////////// // e) Remove the Active Node from the Open List and add it to the // Closed List ///////////////////////////////////////////////////////////////// //OpenList.Remove(currentNode); currentNode.InClosedList = true; } // No path could be found. List <Vector2> l = new List <Vector2>(); l.Add(endPoint); Cleanup(); return(l); }
public virtual bool Intersects(BaseObject theRectangle) { List<Vector2> aRectangleAxis = new List<Vector2>(); aRectangleAxis.Add(UpperRightCorner - UpperLeftCorner); aRectangleAxis.Add(UpperRightCorner - LowerRightCorner); aRectangleAxis.Add(theRectangle.UpperLeftCorner - theRectangle.LowerLeftCorner); aRectangleAxis.Add(theRectangle.UpperLeftCorner - theRectangle.UpperRightCorner); foreach (Vector2 aAxis in aRectangleAxis) { if (!IsAxisCollision(theRectangle, aAxis)) { return false; } } return true; }
public bool Intersects(Rectangle theRectangle) { BaseObject o = new BaseObject(theRectangle, 0.0f); o.CalculateCorners(); return Intersects(o); }
// one list of objects that collide with each other // divide calculation over multiple frames public void UpdatePotentialCollisionsDivided <T>(List <T> list) where T : BaseObject { if (persistentIndex == 0) { Util.SortByX(list); objects = new List <BaseObject>(list); pairs.Clear(); } if (objects.Count == 0) { return; } int numberToDo; if (objects.Count <= SpreadDivisor) { numberToDo = objects.Count; } else { numberToDo = (int)(objects.Count / (float)SpreadDivisor + .5f); } int count = 0; for (; persistentIndex < objects.Count;) // persistentIndex++) { BaseObject object1 = objects[persistentIndex]; for (int s = persistentIndex + 1; s < objects.Count; s++) { BaseObject object2 = objects[s]; if (object2.RightBound < object1.LeftBound) { continue; } if (object2.LeftBound > object1.RightBound) { break; } if (object2.TopBound <= object1.BottomBound && object2.BottomBound >= object1.TopBound) { pairs.Add(new BaseObject[2] { objects[persistentIndex], objects[s] }); } } persistentIndex++; if (++count >= numberToDo && persistentIndex + numberToDo < objects.Count) { return; } } persistentIndex = 0; foreach (BaseObject o in objects) { o.PotentialCollisions.Clear(); } foreach (BaseObject[] pair in pairs) { if (Vector2.Distance(pair[0].CenterPoint, pair[1].CenterPoint) < (pair[0].GreaterOfWidthAndHeight + pair[1].GreaterOfWidthAndHeight) * .8f) { pair[0].PotentialCollisions.Add(pair[1]); pair[1].PotentialCollisions.Add(pair[0]); } } }
public Rts(EventHandler callback) : base(callback) { Game1.Game.DebugMonitor.Position = Direction.NorthEast; Game1.Game.IsMouseVisible = true; //Game1.Game.Graphics.SynchronizeWithVerticalRetrace = false; //Game1.Game.IsFixedTimeStep = false; //Game1.Game.Graphics.ApplyChanges(); GameTimer.Restart(); map = new Map(@"Content/map1.txt"); Unit.Map = map; actualMapWidth = map.Width * map.TileSize; actualMapHeight = map.Height * map.TileSize; Unit.UnitCollisionSweeper.Thread.Suspend(); Unit.UnitCollisionSweeper.Thread.Resume(); Unit.PathFinder.ResumeThread(); uiViewport = GraphicsDevice.Viewport; worldViewport = GraphicsDevice.Viewport; worldViewport.Height -= (minimapSize + minimapBorderSize * 2); GraphicsDevice.Viewport = worldViewport; camera = new Camera(); camera.Pos = new Vector2(worldViewport.Width / 2, worldViewport.Height / 2); button1 = new BaseObject(new Rectangle(10, 25, 25, 25)); button2 = new BaseObject(new Rectangle(10, 52, 25, 25)); button3 = new BaseObject(new Rectangle(10, 79, 25, 25)); button4 = new BaseObject(new Rectangle(10, 106, 25, 25)); button5 = new BaseObject(new Rectangle(10, 133, 25, 25)); if (!contentLoaded) { pauseFont = Content.Load<SpriteFont>("spritefonts/pausefont"); fpsFont = Content.Load<SpriteFont>("spritefonts/fpsfont"); unitInfoUnitNameFont = Content.Load<SpriteFont>("spritefonts/UnitInfoUnitNameFont"); unitInfoHpFont = Content.Load<SpriteFont>("spritefonts/UnitInfoHpFont"); unitInfoKillCountFont = Content.Load<SpriteFont>("spritefonts/UnitInfoKillCountFont"); //brownGuyTexture = Content.Load<Texture2D>("unit textures/browncircleguy"); //brownGuySelectingTexture = Content.Load<Texture2D>("unit textures/browncircleguyselected2"); //brownGuySelectedTexture = Content.Load<Texture2D>("unit textures/browncircleguyselecting2"); greenTeamIndicatorTexture = Content.Load<Texture2D>("unit textures/green team indicator"); redTeamIndicatorTexture = Content.Load<Texture2D>("unit textures/red team indicator"); buttonTexture = Content.Load<Texture2D>("titlebutton1"); moveCommandTexture = Content.Load<Texture2D>("greencircle2"); //normalCursorTexture = Content.Load<Texture2D>("greencursor2"); //attackCommandCursorTexture = Content.Load<Texture2D>("crosshair"); normalCursor = Util.LoadCustomCursor(@"Content/cursors/SC2-cursor.cur"); attackCursor = Util.LoadCustomCursor(@"Content/cursors/SC2-target-none.cur"); boulder1Texture = Content.Load<Texture2D>("boulder1"); tree1Texture = Content.Load<Texture2D>("tree2"); redCircleTexture = Content.Load<Texture2D>("redcircle"); transparentTexture = Content.Load<Texture2D>("transparent"); transparentGrayTexture = Content.Load<Texture2D>("transparentgray"); transparentBlackTexture = Content.Load<Texture2D>("transparentblack"); whiteBoxTexture = Content.Load<Texture2D>("whitebox"); rtsMusic = Content.Load<Song>("sounds/crossingthosehills"); //Unit.BulletTexture = Content.Load<Texture2D>("bullet"); Unit.Explosion1Textures = Util.SplitTexture(Content.Load<Texture2D>("explosionsheet1"), 45, 45); contentLoaded = true; } winForm = (Form)Form.FromHandle(Game1.Game.Window.Handle); winForm.Cursor = normalCursor; VisionUpdater = new VisionUpdater(map, Unit.PathFinder, myTeam); initializeMapTexture(); initializeCommandCardArea(); initializeSelectionInfoArea(); SelectBox.InitializeSelectBoxLine(GraphicsDevice, Color.Green); InitializeSelectionRingLine(GraphicsDevice, Color.Yellow); minimapScreenIndicatorBoxLine = new PrimitiveLine(GraphicsDevice, 1); minimapScreenIndicatorBoxLine.Colour = Color.White; for (int i = 0; i < HotkeyGroups.Length; i++) HotkeyGroups[i] = new List<RtsObject>(); MediaPlayer.Play(rtsMusic); MediaPlayer.Volume = .25f; MediaPlayer.IsRepeating = true; }
public List<Vector2> FindPath(PathNode startNode, Vector2 endPoint, Unit unit, BaseObject target, bool avoidUnits) { // Only try to find a path if the start and end points are different. if (Vector2.Distance(startNode.Tile.CenterPoint, endPoint) <= Map.TileSize) { List<Vector2> list = new List<Vector2>(); list.Add(endPoint); Cleanup(); return list; } /*int startPointY = (int)(startPoint.Y / Map.TILESIZE); int startPointX = (int)(startPoint.X / Map.TILESIZE); if ((startPointY < 0 || startPointY >= Map.Height || startPointX < 0 || startPointX >= Map.Width) || (PathNodes[startPointY, startPointX] == null)) offset = Vector2.Zero; else offset = startNode.Tile.CenterPoint - startPoint;*/ Vector2 startPoint = startNode.Tile.CenterPoint; PathNode endNode = PathNodes[(int)(endPoint.Y / Map.TileSize), (int)(endPoint.X / Map.TileSize)]; currentUnit = unit; ///////////////////////////////////////////////////////////////////// // Step 1 : Clear the Open and Closed Lists and reset each node’s F // and G values in case they are still set from the last // time we tried to find a path. ///////////////////////////////////////////////////////////////////// ResetSearchNodes(); ///////////////////////////////////////////////////////////////////// // Step 2 : Set the start node’s G value to 0 and its F value to the // estimated distance between the start node and goal node // (this is where our H function comes in) and add it to the // Open List. ///////////////////////////////////////////////////////////////////// startNode.InOpenList = true; //if (!avoidUnits) //startNode.DistanceToGoal = HeuristicManhattan(startPoint, endPoint); //else startNode.DistanceToGoal = HeuristicManhattan(startPoint, endPoint); startNode.DistanceTravelled = 0; OpenList.Add(startNode); CleanupList.Add(startNode); ///////////////////////////////////////////////////////////////////// // Setp 3 : While there are still nodes to look at in the Open list : ///////////////////////////////////////////////////////////////////// while (OpenList.Count > 0) { ///////////////////////////////////////////////////////////////// // a) : Loop through the Open List and find the node that // has the smallest F value. ///////////////////////////////////////////////////////////////// PathNode currentNode = FindBestNode(); //pathCount++; ///////////////////////////////////////////////////////////////// // c) : If the Active Node is the goal node, we will // find and return the final path. ///////////////////////////////////////////////////////////////// //if (pathCount >= MaxPathSize) //{ // Cleanup(); // return FindFinalPath(startNode, currentNode, endPoint); //} if (currentNode == endNode) { // Trace our path back to the start. Cleanup(); return FindFinalPath(startNode, currentNode, endPoint); } ///////////////////////////////////////////////////////////////// // d) : Else, for each of the Active Node’s neighbours : ///////////////////////////////////////////////////////////////// for (int i = 0; i < currentNode.Neighbors.Count; i++) { PathNode neighbor = currentNode.Neighbors[i]; ////////////////////////////////////////////////// // i) : Make sure that the neighbouring node can // be walked across. ////////////////////////////////////////////////// if (neighbor.Blocked) { if (target == null || neighbor.Blocker != target) continue; } if (!neighbor.Tile.Walkable) continue; //if (avoidUnits && neighbor.UnitsContained.Count > 0) // continue; ////////////////////////////////////////////////// // ii) Calculate a new G value for the neighbouring node. ////////////////////////////////////////////////// float distanceTravelled; if (currentNode.IsNeighborDiagonal[i]) { if (avoidUnits) distanceTravelled = currentNode.DistanceTravelled + 14; else continue; } else distanceTravelled = currentNode.DistanceTravelled + 10; // An estimate of the distance from this node to the end node. float heuristic; if (!avoidUnits) heuristic = HeuristicManhattan(neighbor.Tile.CenterPoint, endPoint); else { if (currentNode.IsNeighborDiagonal[i]) heuristic = HeuristicManhattan(neighbor.Tile.CenterPoint, endPoint) + (neighbor.UnitsContained.Count * 14); else heuristic = HeuristicManhattan(neighbor.Tile.CenterPoint, endPoint) + (neighbor.UnitsContained.Count * 10); } ////////////////////////////////////////////////// // iii) If the neighbouring node is not in either the Open // List or the Closed List : ////////////////////////////////////////////////// if (!neighbor.InOpenList && !neighbor.InClosedList) { // (1) Set the neighbouring node’s G value to the G value // we just calculated. if (avoidUnits) { if (currentNode.IsNeighborDiagonal[i]) neighbor.DistanceTravelled = distanceTravelled + (neighbor.UnitsContained.Count * 1400000); else neighbor.DistanceTravelled = distanceTravelled + (neighbor.UnitsContained.Count * 1000000); } else neighbor.DistanceTravelled = distanceTravelled; // (2) Set the neighbouring node’s F value to the new G value + // the estimated distance between the neighbouring node and // goal node. // normal A* neighbor.DistanceToGoal = neighbor.DistanceTravelled + heuristic; // best-first //neighbor.DistanceToGoal = heuristic; // (3) Set the neighbouring node’s Parent property to point at the Active // Node. neighbor.Parent = currentNode; // (4) Add the neighbouring node to the Open List. neighbor.InOpenList = true; OpenList.Add(neighbor); CleanupList.Add(neighbor); } ////////////////////////////////////////////////// // iv) Else if the neighbouring node is in either the Open // List or the Closed List : ////////////////////////////////////////////////// else if (neighbor.InOpenList || neighbor.InClosedList) { // (1) If our new G value is less than the neighbouring // node’s G value, we basically do exactly the same // steps as if the nodes are not in the Open and // Closed Lists except we do not need to add this node // the Open List again. if (neighbor.DistanceTravelled > distanceTravelled) { neighbor.DistanceTravelled = distanceTravelled; neighbor.DistanceToGoal = distanceTravelled + heuristic; //neighbor.DistanceToGoal = heuristic; neighbor.Parent = currentNode; } } } ///////////////////////////////////////////////////////////////// // e) Remove the Active Node from the Open List and add it to the // Closed List ///////////////////////////////////////////////////////////////// //OpenList.Remove(currentNode); currentNode.InClosedList = true; } // No path could be found. List<Vector2> l = new List<Vector2>(); l.Add(endPoint); Cleanup(); return l; }