コード例 #1
0
        private IntVector2 AddDoorBetweenRooms(BSPMapNode a, BSPMapNode b)
        {
            int xMin = 0;
            int xMax = 0;
            int yMin = 0;
            int yMax = 0;

            int offsetFromCorner = 2;

            IntVector2 doorLoc = null;

            if (a.position.X == b.position.X + b.width - 1) //A to the right of B
            {
                xMin = xMax = a.position.X;
                yMin = Math.Max(a.position.Y + offsetFromCorner, b.position.Y + offsetFromCorner);
                yMax = Math.Min(a.position.Y + a.height - offsetFromCorner, b.position.Y + b.height - offsetFromCorner);
            }
            else if (a.position.X + a.width - 1 <= b.position.X) //To the left
            {
                xMin = xMax = b.position.X;
                yMin = Math.Max(a.position.Y + offsetFromCorner, b.position.Y + offsetFromCorner);
                yMax = Math.Min(a.position.Y + a.height - offsetFromCorner, b.position.Y + b.height - offsetFromCorner);
            }
            else if (a.position.Y >= b.position.Y + b.height - 1) //Below
            {
                yMin = yMax = a.position.Y;
                xMin = Math.Max(a.position.X + offsetFromCorner, b.position.X + offsetFromCorner);
                xMax = Math.Min(a.position.X + a.width - offsetFromCorner, b.position.X + b.width - offsetFromCorner);
            }
            else if (a.position.Y + a.height - 1 <= b.position.Y) //Above
            {
                yMin = yMax = b.position.Y;
                xMin = Math.Max(a.position.X + offsetFromCorner, b.position.X + offsetFromCorner);
                xMax = Math.Min(a.position.X + a.width - offsetFromCorner, b.position.X + b.width - offsetFromCorner);
            }
            else
            {
                return(null);
            }
            if (xMin > xMax)
            {
                xMin = xMax;
            }
            if (yMin > yMax)
            {
                yMin = yMax;
            }
            int x = rand.Next(xMin, xMax);
            int y = rand.Next(yMin, yMax);

            doorLoc = new IntVector2(x, y);
            //doorLoc = new IntVector2(0, 0);
            a.connectedNodes.Add(b);
            b.connectedNodes.Add(a);

            return(doorLoc);
        }
コード例 #2
0
 public bool IsAdjacent(BSPMapNode other)
 {
     if (position.X >= other.position.X + other.width ||
         position.X + width <= other.position.X ||
         position.Y >= other.position.Y + other.height ||
         position.Y + height <= other.position.Y)
     {
         return(false);
     }
     return(true);
 }
コード例 #3
0
 private void GetLeaves(List <BSPMapNode> leafList, BSPMapNode node)
 {
     if (node.IsLeaf())
     {
         leafList.Add(node);
     }
     else
     {
         GetLeaves(leafList, node.leftLeaf);
         GetLeaves(leafList, node.rightLeaf);
     }
 }
コード例 #4
0
        public BSPMapNode(int height, int width, IntVector2 position, bool sliceAlongXAxis)
        {
            this.height   = height;
            this.width    = width;
            this.position = position;

            this.sliceAlongXAxis = sliceAlongXAxis;
            leftLeaf             = null;
            rightLeaf            = null;

            adjacentNodes  = new List <BSPMapNode>();
            connectedNodes = new List <BSPMapNode>();
        }
コード例 #5
0
        private void AddNodeWallsToMap(LevelData l, BSPMapNode node)
        {
            int x = 0;
            int y = 0;

            for (x = node.position.X; x < node.position.X + node.width; x++)
            {
                l.tiles[x, node.position.Y] = new TileData(new IntVector2(x, node.position.Y), "wall");                                     //Top
                l.tiles[x, node.position.Y + node.height - 1] = new TileData(new IntVector2(x, node.position.Y + node.height - 1), "wall"); //Bottom
            }

            for (y = node.position.Y; y < node.position.Y + node.height; y++)
            {
                l.tiles[node.position.X, y] = new TileData(new IntVector2(node.position.X, y), "wall");                                   //Left
                l.tiles[node.position.X + node.width - 1, y] = new TileData(new IntVector2(node.position.X + node.width - 1, y), "wall"); //Right
            }
        }
コード例 #6
0
 private bool FindPathToNode(List <BSPMapNode> path, BSPMapNode current, BSPMapNode destination)
 {
     path.Add(current);
     if (current.adjacentNodes.Contains(destination))
     {
         path.Add(destination);
         return(true);
     }
     else
     {
         foreach (BSPMapNode node in current.adjacentNodes)
         {
             if (!path.Contains(node) && FindPathToNode(path, node, destination))
             {
                 return(true);
             }
         }
     }
     path.Remove(current);
     return(false);
 }
コード例 #7
0
        public List <MapGen_Room> GenerateMap(LevelData level)
        {
            rand       = new Random();
            this.level = level;

            GenerateMapFrame(level);

            BSPMapNode topNode = new BSPMapNode(height, width, new IntVector2(0, 0), true);

            RecursivelySubdivideNode(topNode, 0); //Create the room structure

            //Get all the leaves of the tree (the actual rooms)
            List <BSPMapNode> leaves = new List <BSPMapNode>();

            GetLeaves(leaves, topNode);

            //Choose 2 random ones to have stairs
            BSPMapNode upStairsRoom   = leaves[rand.Next(leaves.Count)];
            BSPMapNode downStairsRoom = upStairsRoom;

            while (downStairsRoom == upStairsRoom || downStairsRoom.IsAdjacent(upStairsRoom))
            {
                downStairsRoom = leaves[rand.Next(leaves.Count)];
            }

            //Find the "critical path" between stairs
            List <BSPMapNode> stairPath = new List <BSPMapNode>();
            bool success = FindPathToNode(stairPath, upStairsRoom, downStairsRoom);

            if (!success)
            {
                throw new Exception("Couldn't find a path between stairs for god knows what reason");
            }

            List <IntVector2> doors = new List <IntVector2>();

            //Add doors to the stairs
            for (int i = 0; i < stairPath.Count - 1; i++)
            {
                doors.Add(AddDoorBetweenRooms(stairPath[i], stairPath[i + 1]));
            }

            //Go thru the list of rooms and try to give each one at least two doors
            foreach (BSPMapNode node in leaves)
            {
                while (node.connectedNodes.Count < 2 && node.connectedNodes.Count < node.adjacentNodes.Count)
                {
                    BSPMapNode nodeToConnect = node.adjacentNodes[rand.Next(node.adjacentNodes.Count)];
                    if (!node.connectedNodes.Contains(nodeToConnect))
                    {
                        doors.Add(AddDoorBetweenRooms(node, nodeToConnect));
                    }
                }
            }


            //Add doors to map
            foreach (IntVector2 door in doors)
            {
                level.tiles[door.X, door.Y] = new TileData(door, "door");
            }

            //Add stairs to map
            IntVector2 upStairsTile   = new IntVector2(upStairsRoom.position.X + upStairsRoom.width / 2, upStairsRoom.position.Y + upStairsRoom.height / 2);
            IntVector2 downStairsTile = new IntVector2(downStairsRoom.position.X + downStairsRoom.width / 2, downStairsRoom.position.Y + downStairsRoom.height / 2);

            //level.tiles[upStairsTile.X, upStairsTile.Y] = level.upstairsTile = new TileData(upStairsTile, "upstairs");
            //level.tiles[downStairsTile.X, downStairsTile.Y] = level.downstairsTile = new TileData(downStairsTile, "downstairs");

            //Output rooms as MapGen_Room objects
            List <MapGen_Room> roomList = new List <MapGen_Room>();

            foreach (BSPMapNode node in leaves)
            {
                string roomType = "normal";
                if (node == upStairsRoom)
                {
                    roomType = "upstairsroom";
                }
                else if (node == downStairsRoom)
                {
                    roomType = "downstairsroom";
                }
                roomList.Add(new MapGen_Room(node.position, new IntVector2(node.width, node.height), roomType));
            }

            return(roomList);
        }
コード例 #8
0
        private void RecursivelySubdivideNode(BSPMapNode node, int subdivisionDepth)
        {
            //Check if this node is out of subdivision depth
            if (subdivisionDepth > numOfSubdivisions)
            {
                return;
            }

            //Check if this node is too small to subdivide and establish division point
            int divisionPoint = 0;

            if (node.sliceAlongXAxis)
            {
                if (node.height - (minRoomDimensions * 2) < 0)
                {
                    return;
                }
                else
                {
                    divisionPoint = rand.Next(minRoomDimensions, node.height - minRoomDimensions);
                }
            }
            else
            {
                if (node.width - (minRoomDimensions * 2) < 0)
                {
                    return;
                }
                else
                {
                    divisionPoint = rand.Next(minRoomDimensions, node.width - minRoomDimensions);
                }
            }

            //Slice node
            if (node.sliceAlongXAxis)
            {
                node.leftLeaf  = new BSPMapNode(divisionPoint, node.width, new IntVector2(node.position.X, node.position.Y), false);
                node.rightLeaf = new BSPMapNode(node.height + 1 - divisionPoint, node.width, new IntVector2(node.position.X, node.position.Y + divisionPoint - 1), false);
            }
            else
            {
                node.leftLeaf  = new BSPMapNode(node.height, divisionPoint, new IntVector2(node.position.X, node.position.Y), true);
                node.rightLeaf = new BSPMapNode(node.height, node.width + 1 - divisionPoint, new IntVector2(node.position.X + divisionPoint - 1, node.position.Y), true);
            }

            AddNodeWallsToMap(level, node.leftLeaf);
            AddNodeWallsToMap(level, node.rightLeaf);

            //Figure out neighbors
            //Obviously both leaves are neighbors of each other
            node.leftLeaf.adjacentNodes.Add(node.rightLeaf);
            node.rightLeaf.adjacentNodes.Add(node.leftLeaf);
            //Any nodes adjacent to this one could be adjacent to the leaves, test them
            //Also now that I'm not a leaf nobody cares who I'm adjacent to so get rid of their refs to me
            foreach (BSPMapNode n in node.adjacentNodes)
            {
                if (n.IsAdjacent(node.leftLeaf))
                {
                    node.leftLeaf.adjacentNodes.Add(n);
                    n.adjacentNodes.Add(node.leftLeaf);
                }
                if (n.IsAdjacent(node.rightLeaf))
                {
                    node.rightLeaf.adjacentNodes.Add(n);
                    n.adjacentNodes.Add(node.rightLeaf);
                }
                n.adjacentNodes.Remove(node);
            }

            //Subdivide the largest node next
            if (node.leftLeaf.width > node.rightLeaf.width || node.leftLeaf.height > node.rightLeaf.height)
            {
                RecursivelySubdivideNode(node.leftLeaf, subdivisionDepth + 1);
                if (rand.Next(2) < 1 || subdivisionDepth < 1)
                {
                    RecursivelySubdivideNode(node.rightLeaf, subdivisionDepth + 1);
                }
            }
            else
            {
                RecursivelySubdivideNode(node.rightLeaf, subdivisionDepth + 1);
                if (rand.Next(2) < 1 || subdivisionDepth < 1)
                {
                    RecursivelySubdivideNode(node.leftLeaf, subdivisionDepth + 1);
                }
            }
        }