public static MovementPath AStar(Point start, Point end, Stage stage = null) { MovementPath newPath = new MovementPath(null); if (stage == null) { stage = Stage.CurrentStage; } // setup grid with walls //MyPathNode[,] grid = new MyPathNode[(int)stage.Width, (int)stage.Height]; MyPathNode[][] grid = new MyPathNode[(int)stage.Width][]; for (int x = 0; x < (int)stage.Width; x++) { grid[x] = new MyPathNode[(int) stage.Height]; for (int y = 0; y < (int)stage.Height; y++) { grid[x][y] = new MyPathNode() { IsWall = stage.GetTileAt(x, y).GetWalkable(), X = x, Y = y, }; } } SpatialAStar<MyPathNode, Object> aStar = new SpatialAStar<MyPathNode, Object>(grid); LinkedList<MyPathNode> path = aStar.Search(new Point(0, 0), new Point(stage.Width - 2, stage.Height - 2), null); return null; }
// Resolve the map's path legs for a given dimension private static void resolvePathLegs(Stage stage, bool vertical, ref Dictionary<short, List<PathLeg>> returnVals) { short col = 0; short row = 0; short legStart = -1; short legEnd = -1; if (vertical) { // Loop through all of the rows while (col < stage.Width) { returnVals[col] = new List<PathLeg>(); // Loop through all of the columns in this row ... while (row < stage.Height) { // If the tile is passable by entities. if (stage.GetTileAt(col, row).GetWalkable()) { // If we're in a leg, extend it if (legStart != -1) { legEnd = row; } // Start a new leg else { legStart = row; } } else { // If we had a leg going, store it. if (legStart != -1 && legEnd != -1) { returnVals[col].Add(new PathLeg(new Point(col, legStart), new Point(col, legEnd), vertical)); } legStart = -1; legEnd = -1; } row++; } row = 0; col++; } } else { // Loop through all of the rows while (row < stage.Height) { returnVals[row] = new List<PathLeg>(); // Loop through all of the columns in this row ... while (col < stage.Width) { // If the tile is passable by entities. if (stage.GetTileAt(col, row).GetWalkable()) { // If we're in a leg, extend it if (legStart != -1) { legEnd = col; } // Start a new leg else { legStart = col; } } else { // If we had a leg going, store it. if (legStart != -1 && legEnd != -1) { returnVals[row].Add(new PathLeg(new Point(legStart, row), new Point(legEnd, row), vertical)); } legStart = -1; legEnd = -1; } col++; } col = 0; row++; } } }
// Resolve a single (horizontal or vertical) leg of a path between two points. private static List<Point> resolveLeg(Point start, Point end, Stage stage, bool vertical) { List<Point> resultPath = new List<Point>(); Point currentPoint = start; resultPath.Add(start); if (vertical) { // Positive movement if (end.y > start.y) { while (stage.GetTileAt((int)currentPoint.x, (int)currentPoint.y + 1) != null && stage.GetTileAt((int)currentPoint.x, (int)currentPoint.y + 1).GetWalkable()) { currentPoint = new Point(currentPoint.x, currentPoint.y + 1); resultPath.Add(currentPoint); } } // Negative movement else { while (stage.GetTileAt((int)currentPoint.x, (int)currentPoint.y - 1) != null && stage.GetTileAt((int)currentPoint.x, (int)currentPoint.y - 1).GetWalkable()) { currentPoint = new Point(currentPoint.x, currentPoint.y - 1); resultPath.Add(currentPoint); } } } // Horizontal else { // Positive movement if (end.x > start.x) { while (stage.GetTileAt((int)currentPoint.x + 1, (int)currentPoint.y) != null && stage.GetTileAt((int)currentPoint.x + 1, (int)currentPoint.y).GetWalkable()) { currentPoint = new Point(currentPoint.x + 1, currentPoint.y); resultPath.Add(currentPoint); } } // Negative movement else { while (stage.GetTileAt((int)currentPoint.x - 1, (int)currentPoint.y) != null && stage.GetTileAt((int)currentPoint.x - 1, (int)currentPoint.y).GetWalkable()) { currentPoint = new Point(currentPoint.x - 1, currentPoint.y); resultPath.Add(currentPoint); } } } // Check the point at the end of the path to make sure it's accessible from two directions // Remove points from the end until the last point is accessible from two directions. return resultPath; }
// Get the longest passage connected to a point private static MovementDirection longestPassage(Point point, Stage stage) { short longestPassage = 0; MovementDirection longestDirection = MovementDirection.None; Point currentPoint = point; short passageLength = 0; // Check Right while (stage.GetTileAt((int) currentPoint.x + 1, (int) currentPoint.y) != null && stage.GetTileAt((int) currentPoint.x + 1, (int) currentPoint.y).GetWalkable()) { currentPoint = new Point(currentPoint.x + 1, currentPoint.y); passageLength++; } if (passageLength > longestPassage) { longestDirection = MovementDirection.Right; } passageLength = 0; currentPoint = point; // Check Left while (stage.GetTileAt((int)currentPoint.x - 1, (int)currentPoint.y) != null && stage.GetTileAt((int)currentPoint.x - 1, (int)currentPoint.y).GetWalkable()) { currentPoint = new Point(currentPoint.x - 1, currentPoint.y); passageLength++; } if (passageLength > longestPassage) { longestDirection = MovementDirection.Left; } passageLength = 0; currentPoint = point; // Check Up while (stage.GetTileAt((int)currentPoint.x, (int)currentPoint.y + 1) != null && stage.GetTileAt((int)currentPoint.x, (int)currentPoint.y + 1).GetWalkable()) { currentPoint = new Point(currentPoint.x, currentPoint.y + 1); passageLength++; } if (passageLength > longestPassage) { longestDirection = MovementDirection.Up; } passageLength = 0; currentPoint = point; // Check Down while (stage.GetTileAt((int)currentPoint.x, (int)currentPoint.y - 1) != null && stage.GetTileAt((int)currentPoint.x, (int)currentPoint.y - 1).GetWalkable()) { currentPoint = new Point(currentPoint.x, currentPoint.y - 1); passageLength++; } if (passageLength > longestPassage) { longestDirection = MovementDirection.Down; } return longestDirection; }
//resolve the shortest path between two given points public static MovementPath ResolvePath2(Point start, Point end, Stage stage = null) { MovementPath newPath = new MovementPath(null); if (stage == null) { stage = Stage.CurrentStage; } // The last point added Point currentPoint = start; //need better pathfinding and collision detection later // Add the beginning newPath.AddPoint(start); // List all of the avenues we've explored List<PathLeg> pathLegs = new List<PathLeg>(); // Start from the start and explore the legs // March repeatedly through each path, until reaching the exit or a dead end //if there's horizontal distance to cover between the points, cover it first while(currentPoint.x != end.x) { // If we can move to the next tile, do so if (stage.GetTileAt((int)currentPoint.x + 1, (int)currentPoint.y).GetWalkable()) { currentPoint = new Point(currentPoint.x + 1, currentPoint.y); newPath.AddPoint(currentPoint); } // If not, switch to vertical differencing ... else { } } return newPath; }