Esempio n. 1
0
    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);
            }
        }
    }
Esempio n. 2
0
    //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);
    }
Esempio n. 3
0
        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);
    }