Пример #1
0
        /// <summary> Creates all of the rooms on the map. </summary>
        /// <param name="splits"> The amount of times a room should be split. </param>
        public void CreateRooms(int splits)
        {
            Root = new Room(0, 0, Width, Height, null);
            _tileMap = new int[Width, Height];

            SetupTileMap(_tileMap);
            RecursiveSplit(splits, Root);
            GenerateTileMap(Root);
        }
Пример #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Room"/> class.
        /// </summary>
        /// <param name="x">The top-left x coordinate.</param>
        /// <param name="y">The top-left y coordinate.</param>
        /// <param name="width">The width of the room.</param>
        /// <param name="height">The height of the room.</param>
        /// <param name="parent">The parent of this room.</param>
        public Room(int x, int y, int width, int height, Room parent)
        {
            _doors = new bool[width + 1, height + 1];
            _occupied = new bool[width, height];

            RoomRect = new Rect(x, y, width, height);
            Parent = parent;

            Enemies = new List<Enemy>();
            Items = new List<Item>();

            Transparent = false;
        }
Пример #3
0
        public static Directions DirectionEnum(Room room, Vector door)
        {
            if ((int)door.X == (int)room.RoomRect.X)
            {
                return Directions.Left;
            }

            if ((int)door.X == (int)(room.RoomRect.X + room.RoomRect.Width - 1))
            {
                return Directions.Right;
            }

            if ((int)door.Y == (int)room.RoomRect.Y)
            {
                return Directions.Down;
            }

            return Directions.Up;
        }
Пример #4
0
        /// <summary> Recursively creates the BSPs. </summary>
        /// <param name="splits"> The current number of remaining splits a room can have. </param>
        /// <param name="node"> The room to be split. </param>
        private void RecursiveSplit(int splits, Room node, int enumeration = 0)
        {
            // Avoid an infinite loop
            if (enumeration >= 1000)
            {
                return;
            }

            // Get the x and y-ranges.
            var xrange1 = (int)node.RoomRect.Left + _minRoomSize;
            var xrange2 = (int)node.RoomRect.Right - _minRoomSize;
            var yrange1 = (int)node.RoomRect.Top + _minRoomSize;
            var yrange2 = (int)node.RoomRect.Bottom - _minRoomSize;

            // Check if the room is already too small to cut.
            if (splits <= 0 || (xrange1 > xrange2 && yrange1 > yrange2))
            {
                node.Deleted = StaticRandom.Random.NextDouble() <= _removeProbability;
                return;
            }

            // Initialize variables.
            int pos, door;
            Room.CutDirections dir;

            // Cut horizontally if the room is too small horizontally.
            if (xrange1 > xrange2)
            {
                dir = Room.CutDirections.Horizontal;
            }
            // Cut vertically if the room is too small vertically.
            else if (yrange1 > yrange2)
            {
                dir = Room.CutDirections.Vertical;
            }
            // Cut randomly if the room is large enough.
            else
            {
                var length = Enum.GetValues(typeof(Room.CutDirections)).Length;
                dir = (Room.CutDirections)StaticRandom.Random.Next(0, length);
            }

            // Depending on the cut direction, set up where the cut will be and where the door will be.
            if (dir == Room.CutDirections.Horizontal)
            {
                var tries = 0; // If you can't find a split after 1000 tries, guessing is probably OK
                do
                {
                    pos = StaticRandom.Random.Next(yrange1, yrange2);
                    tries++;
                } while (node.Parent != null && (IsOnDoor(node.Parent, dir, pos)) && tries < MaxTries);

                door = StaticRandom.Random.Next((int) node.RoomRect.Left + 1, (int) node.RoomRect.Right - 1);
            }
            else
            {
                var tries = 0;
                do
                {
                    pos = StaticRandom.Random.Next(xrange1, xrange2);
                    tries++;
                } while (node.Parent != null && (IsOnDoor(node.Parent, dir, pos)) && tries < MaxTries);

                door = StaticRandom.Random.Next((int)node.RoomRect.Top + 1, (int)node.RoomRect.Bottom - 1);
            }

            // Split the room.
            node.SplitRoom(dir, new Vector(pos, pos), door);
            // Recursively cut the room's children.
            RecursiveSplit(splits - 1, node.ChildA, enumeration + 1);
            RecursiveSplit(splits - 1, node.ChildB, enumeration + 1);
        }
Пример #5
0
        private bool IsOnDoor(Room current, Room.CutDirections dir, int pos)
        {
            if (current == null) return false;

            if (dir != current.Split.Direction && current.Split.Door == pos)
            {
                return true;
            }

            return IsOnDoor(current.Parent, dir, pos);
        }
Пример #6
0
        private void GenerateTileMap(Room node)
        {
            if (node == null) return;

            if (node.Transparent)
            {
                GenerateTileMap(node.ChildA);
                GenerateTileMap(node.ChildB);
            }
            else
            {
                node.PlaceRoom(ref _tileMap);
            }
        }
Пример #7
0
        /// <summary> Split the room with a direction and position. </summary>
        /// <param name="direction"> The direction of the split. </param>
        /// <param name="position"> Where the split is located. </param>
        /// <param name="door"> Where the door is located on the split. </param>
        public void SplitRoom(CutDirections direction, Vector position, int door)
        {
            Split = new Cut { Direction = direction, Position = position, Door = door };
            Transparent = true;

            if (direction == CutDirections.Horizontal)
            {
                var x = (int)RoomRect.Left;
                var y1 = (int)RoomRect.Top;
                var y2 = (int)Split.Position.Y;

                var width = (int)RoomRect.Width;
                var height1 = (int)(Split.Position.Y - RoomRect.Top + 1);
                var height2 = (int)(RoomRect.Bottom - Split.Position.Y);

                ChildA = new Room(x, y1, width, height1, this);
                ChildB = new Room(x, y2, width, height2, this);

                ChildA.AddDoor(door, (int)position.Y);
                ChildB.AddDoor(door, (int)position.Y);
            }
            else
            {
                var x1 = (int)RoomRect.Left;
                var x2 = (int)Split.Position.X;
                var y = (int)RoomRect.Top;

                var width1 = (int)(Split.Position.Y - RoomRect.Left + 1);
                var width2 = (int)(RoomRect.Right - Split.Position.X);
                var height = (int)RoomRect.Height;

                ChildA = new Room(x1, y, width1, height, this);
                ChildB = new Room(x2, y, width2, height, this);

                ChildA.AddDoor((int)position.X, door);
                ChildB.AddDoor((int)position.X, door);
            }

            // Add parent doors to room
            var parent = this;

            while (parent != null)
            {
                for (var y = (int)parent.RoomRect.Y; y < parent.RoomRect.Y + parent.RoomRect.Height; y++)
                {
                    for (var x = (int)parent.RoomRect.X; x < parent.RoomRect.X + parent.RoomRect.Width; x++)
                    {
                        if (!parent.GetDoor(x, y)) continue;

                        ChildA.AddDoor(x, y);
                        ChildB.AddDoor(x, y);
                    }
                }

                parent = parent.Parent;
            }
        }