Esempio n. 1
0
    // Adds both secondary room and corridor tile positions to `_data`. Secondary rooms are the ones
    // intersecting the corridors.
    private void AddCorridors()
    {
        //Stores existing connections in its keys.
        var connected = new Dictionary <Vector2, object>();

        //Checks if points are connected by a corridor. If not, adds a corridor.

        foreach (int point1Id in _path.GetPoints())
        {
            foreach (var point2Id in _path.GetPointConnections(point1Id))
            {
                var point1 = _path.GetPointPosition(point1Id);
                var point2 = _path.GetPointPosition(point2Id);

                if (connected.ContainsKey(new Vector2(point1Id, point2Id)))
                {
                    continue;;
                }

                point1 = Level.WorldToMap(point1);
                point2 = Level.WorldToMap(point2);

                AddCorridor((int)point1.x, (int)point2.x, (int)point1.y, Vector2.Axis.X);
                AddCorridor((int)point1.x, (int)point2.x, (int)point2.y, Vector2.Axis.Y);

                //Stores the connection between point 1 and 2.
                connected[new Vector2(point1Id, point2Id)] = null;
                connected[new Vector2(point2Id, point1Id)] = null;
            }
        }
    }
Esempio n. 2
0
    // Called every time stabilizes (mode changes to RigidBody2D.MODE_STATIC).
    //
    // Once all rooms have stabilized it calculates a playable dungeon `_path` using the MST
    // algorithm. Based on the calculated `_path`, it populates `_data` with room and corridor tile
    // positions.
    //
    // It emits the "rooms_placed" signal when it finishes so we can begin the tileset placement.
    private void _on_Room_sleeping_state_changed()
    {
        GD.Print("_on_Room_sleeping_state_changed");

        _sleepingRooms++;
        if (_sleepingRooms < MaxRooms)
        {
            return;
        }

        var mainRooms          = new List <Room>();
        var mainRoomsPositions = new List <Vector2>();

        foreach (Room room in Rooms.GetChildren())
        {
            if (IsMainRoom(room))
            {
                mainRooms.Add(room);
                mainRoomsPositions.Add(room.Position);
            }
        }

        _path = Utils.MST(mainRoomsPositions);

        foreach (int point1Id in _path.GetPoints())
        {
            foreach (int point2Id in _path.GetPoints())
            {
                if (point1Id != point2Id &&
                    !_path.ArePointsConnected(point1Id, point2Id) &&
                    _rng.Randf() < ReconnectionFactor)
                {
                    _path.ConnectPoints(point1Id, point2Id);
                }
            }
        }

        foreach (Room room in mainRooms)
        {
            AddRoom(room);
        }
        AddCorridors();

        SetProcess(false);
        EmitSignal(nameof(RoomsPlaced));
    }
Esempio n. 3
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. 4
0
    public void UpdateNavigationMap()
    {
        foreach (int pointID in _aStar.GetPoints())
        {
            _aStar.SetPointDisabled(pointID, false);
            _gridRects[pointID].Color = _enableColor;
        }

        Godot.Collections.Array obstacles = GetTree().GetNodesInGroup("Obstacles");

        foreach (Node2D obstacle in obstacles)
        {
            if (obstacle is TileMap)
            {
                TileMap tileMap = (TileMap)obstacle;
                foreach (Vector2 tile in tileMap.GetUsedCells())
                {
                    int tileID = getPointID((int)tile.x, (int)tile.y);
                    if (_aStar.HasPoint(tileID))
                    {
                        _aStar.SetPointDisabled(tileID, true);
                        _gridRects[tileID].Color = _disableColor;
                    }
                }
            }
            else if (obstacle is Agent)
            {
                Vector2 tile   = _tileMap.WorldToMap(obstacle.GlobalPosition);
                int     tileID = getPointID((int)tile.x, (int)tile.y);
                if (_aStar.HasPoint(tileID))
                {
                    _aStar.SetPointDisabled(tileID, true);
                    _gridRects[tileID].Color = _disableColor;
                }
            }
        }
    }