public void _addTraversableTiles(Godot.Collections.Array tiles) { foreach (Vector2 tile in tiles) { int id = getPointID((int)tile.x, (int)tile.y); if (!_aStar.HasPoint(id)) { _aStar.AddPoint(id, tile, 1); _tilestoWorld.Add(id, _tileMap.MapToWorld(tile) + _halfCellSize); ColorRect colorRect = new ColorRect(); _grid.AddChild(colorRect); colorRect.Color = _enableColor; colorRect.Modulate = new Color(1, 1, 1, 0.5f); _gridRects.Add(id, colorRect); colorRect.MouseFilter = Control.MouseFilterEnum.Ignore; colorRect.SetSize(_tileMap.CellSize); // Color Rect's x calculation is lightly different, so need to add 1.5f to position correctly colorRect.RectPosition = new Vector2(_tileMap.MapToWorld(tile).x + (_tileMap.CellSize.x * 1.5f), _tileMap.MapToWorld(tile).y); } } }
//Calculates the Minimum Spanning Tree (MST) for given points and returns an `AStar2D` graph using Prim's algorithm. // https://en.wikipedia.org/wiki/Prim%27s_algorithm // https://en.wikipedia.org/wiki/Minimum_spanning_tree public static AStar2D MST(List <Vector2> pointsList) { var result = new AStar2D(); var firstPoint = pointsList.LastOrDefault(); //Start from an arbitrary point in the list of points result.AddPoint(result.GetAvailablePointId(), firstPoint); pointsList.Remove(firstPoint); //Loop through all points, erasing them as we connect them. while (pointsList.Any()) { var currentPosition = Vector2.Zero; var minPosition = Vector2.Zero; var minDistance = float.PositiveInfinity; foreach (int point1Id in result.GetPoints()) { //Compare each point added to the Astar2D graph to each remaining point to find the closest one var point1Position = result.GetPointPosition(point1Id); foreach (var point2Position in pointsList) { var distance = point1Position.DistanceTo(point2Position); if (minDistance > distance) { //We use the variables to store the coordinates of the closest point. //We have to loop over all points to ensure it's the closest. currentPosition = point1Position; minPosition = point2Position; minDistance = distance; } } } //Connect the point closest to the "current position" with our new point var pointId = result.GetAvailablePointId(); result.AddPoint(pointId, minPosition); result.ConnectPoints(result.GetClosestPoint(currentPosition), pointId); pointsList.Remove(minPosition); } return(result); }
private void ConnectCornerCells() { // find all cells with a higher (lower on the screen) y value AND an x value to the right (if right corner) or to the left (if left corner) AND within the max distance foreach (var cornerCell in _astarCornerCells) { IEnumerable <AstarCell> cellsToConnect; if (cornerCell.IsLeftCorner) { cellsToConnect = _astarCells .Where(cell => cell.Position.y > cornerCell.Position.y && cell.Position.x < cornerCell.Position.x - 2 && cell.Position.DistanceSquaredTo(cornerCell.Position) <= MAX_CELL_DISTANCE * MAX_CELL_DISTANCE ); } else { cellsToConnect = _astarCells .Where(cell => cell.Position.y > cornerCell.Position.y && cell.Position.x > cornerCell.Position.x + 2 && cell.Position.DistanceSquaredTo(cornerCell.Position) <= MAX_CELL_DISTANCE * MAX_CELL_DISTANCE ); } // for each cell that matches the above conditions // create a new astar cell at the corner position with a weight equal to the distance of the cell to connect to // then connect the two cells together foreach (var toConnectCell in cellsToConnect) { var dist = toConnectCell.Position.DistanceTo(cornerCell.Position); _astar.AddPoint(_astarId, cornerCell.Position, dist); _astar.ConnectPoints(toConnectCell.Id, _astarId, true); // connect new corner cell to "real" corner cell to complete the loop if (_positionToCell.ContainsKey(cornerCell.Position)) { _astar.ConnectPoints(_positionToCell[cornerCell.Position].Id, _astarId, true); } _astarId++; } } }
private List <Vector2> CalculateAStarWalkableCells(List <Vector2> obstacleCells) { List <Vector2> walkableCells = new List <Vector2>(); for (int y = 0; y < this.mapSize.y; y++) { for (int x = 0; x < this.mapSize.x; x++) { Vector2 cell = new Vector2(x, y); if (!obstacleCells.Contains(cell)) { walkableCells.Add(cell); int cellIndex = CalculateCellIndex(cell); aStarNode.AddPoint(cellIndex, new Vector2(cell.x, cell.y)); } } } return(walkableCells); }