Yobi_Gochida

Dungeon Generator

Sep 3rd, 2015
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.42 KB | None | 0 0
  1.  
  2.     #region Dungeon Layout Generation
  3.     /// <summary>
  4.     /// This is where dungeon generation customization should go.
  5.     /// </summary>
  6.     public void GenerateDungeon(int roomCount)
  7.     {
  8.         Stopwatch swatch = new Stopwatch();  //diagnostic
  9.         long totalTime = 0;  //diagnostic
  10.  
  11.         if (_dunLevel.roomList.Count == 0) //if we have no tiles, i.e. no dungeon created...
  12.         {
  13.             //load dungeon specific textures and sprites
  14.             //string floorTexPath = "Textures/floor_tex";
  15.  
  16.             //create our initial room. We'll start growing rooms from this.
  17.             GameObject roomObj = Sys.LoadPrefab("Prefabs/floor_prefab");
  18.             FloorMesh floorMesh = roomObj.GetComponent<FloorMesh>();
  19.             FloorData aRoom = new FloorData();
  20.  
  21.             aRoom.width = Random.Range(4, 9); //pick a random room size
  22.             aRoom.height = Random.Range(4, 9);
  23.  
  24.             aRoom.x = 250;
  25.             aRoom.y = 250;
  26.             aRoom.z = GameState.FLOOR_Z_DEPTH;
  27.             aRoom.texPath = "Textures/floor_tex_4";
  28.  
  29.             roomObj.transform.position = new Vector3(aRoom.x, aRoom.y, aRoom.z);
  30.             roomObj.transform.SetParent(_dunLevel.floorParent);
  31.             floorMesh.GenerateMesh(aRoom);
  32.  
  33.             _dunLevel.roomList.Add(aRoom);
  34.             _dunLevel.meshList.Add(floorMesh);
  35.  
  36.             swatch.Start(); //diagnostic
  37.             for (int roomsCreated = 0; roomsCreated < roomCount;)                                     //create "RoomCount" amount of rooms.
  38.             {//if you're going to change how the dungeon is created, it should mostly go here.
  39.                 #region Room Creation
  40.         //all this does is make a room of random width and height between 4 and 8.
  41.         //More advanced stuff could go here, like a first pass to create corridors
  42.         //then a second pass to create rooms
  43.         //then a third pass to create special rooms
  44.                 FloorData startRoom = GetRandomRoom();
  45.                 FloorData newRoom = new FloorData();
  46.                 newRoom.width = Random.Range(4, 9); //pick a random room size
  47.                 newRoom.height = Random.Range(4, 9);                                            //pick a random room size
  48.  
  49.                 PositionRoom(startRoom, newRoom); //this picks a random wall to grow the room from.
  50.                
  51.                 if(TryCreateRoom(startRoom, newRoom))
  52.                 { //TryCreateRoom checks to see if any room overlaps the new one, and creates the room if there's no overlaps
  53.                     roomsCreated++;                                                //IMPORTANT: We must increment this every time a room is created!
  54.                 }
  55.                 #endregion Room Creation
  56.             }
  57.             swatch.Stop(); //diagnostic
  58.             totalTime += swatch.ElapsedMilliseconds; //diagnostic
  59.             UnityEngine.Debug.Log("Dungeon generated in " + swatch.ElapsedMilliseconds + " milliseconds"); //diagnostic
  60.  
  61.             swatch.Reset(); //diagnostic
  62.             swatch.Start(); //diagnostic
  63.             AddWallsToRooms();
  64.             swatch.Stop();  //diagnostic
  65.             totalTime += swatch.ElapsedMilliseconds;  //diagnostic
  66.             UnityEngine.Debug.Log("Walls generated in " + swatch.ElapsedMilliseconds + " milliseconds");  //diagnostic
  67.  
  68.             RemoveOverlappingWalls();
  69.         }
  70.         UnityEngine.Debug.Log("Total time spent: " + totalTime + " milliseconds");  //diagnostic
  71.     }
  72.     #endregion
  73.  
  74.     #region Dungeon Generation Helpers
  75.     /// <summary>
  76.     /// grabs a random room from the list
  77.     /// </summary>
  78.     protected FloorData GetRandomRoom()
  79.     {
  80.         int index = (int)Random.Range(0, _dunLevel.roomList.Count);
  81.         return _dunLevel.roomList[index];                    //pick a room in the list at random
  82.     }
  83.  
  84.     //places a room next to another randomly
  85.     protected void PositionRoom(FloorData startRoom, FloorData newRoom)
  86.     {
  87.         int wallChoice = Random.Range(1, 5);                            //pick a random wall. 1 is north, 2 east, 3 south, 4 west
  88.  
  89.         float yPos = 0;
  90.         float xPos = 0;
  91.  
  92.         if (wallChoice == 1) //north wall. newRoom goes ABOVE startRoom
  93.         {
  94.             //find the bottom left corner position of the room. Rooms build up and to the right
  95.             //start at X, move over half startRooms width. Move back half the newRooms width. Should align the center of both rooms.
  96.             xPos = startRoom.x + (startRoom.width / 2) - (newRoom.width / 2);
  97.             yPos = startRoom.y + startRoom.height + 1;
  98.  
  99.             newRoom.texPath = "Textures/floor_tex_5";
  100.         }
  101.         else if (wallChoice == 2)
  102.         {
  103.             //find the bottom left corner position of the room. Rooms build up and to the right
  104.             xPos = startRoom.x + startRoom.width + 1;
  105.             //start at Y, move up half startRooms height. Move back half the newRooms height. Should align the center of both rooms.
  106.             yPos = startRoom.y + (startRoom.height / 2) - (newRoom.height / 2);
  107.  
  108.             newRoom.texPath = "Textures/floor_tex_1";
  109.         }
  110.         else if (wallChoice == 3)
  111.         {
  112.             //find the bottom left corner position of the room. Rooms build up and to the right
  113.             //start at X, move over half startRooms width. Move back half the newRooms width. Should align the center of both rooms.
  114.             xPos = startRoom.x + (startRoom.width / 2) - (newRoom.width / 2);
  115.             yPos = startRoom.y - newRoom.height - 1;
  116.  
  117.             newRoom.texPath = "Textures/floor_tex_2";
  118.         }
  119.         else //wallChoice == 4+
  120.         {
  121.             //find the bottom left corner position of the room. Rooms build up and to the right
  122.             xPos = startRoom.x - newRoom.width - 1;
  123.             //start at Y, move up half startRooms height. Move back half the newRooms height. Should align the center of both rooms.
  124.             yPos = startRoom.y + (startRoom.height / 2) - (newRoom.height / 2);
  125.  
  126.             newRoom.texPath = "Textures/floor_tex_3";
  127.         }
  128.  
  129.         newRoom.x = xPos;
  130.         newRoom.y = yPos;
  131.         newRoom.z = GameState.FLOOR_Z_DEPTH;
  132.     }
  133.  
  134.     protected bool TryCreateRoom(FloorData startRoom, FloorData newRoom)
  135.     {
  136.         bool invalid = false;
  137.         foreach (FloorData existingRoom in _dunLevel.roomList)
  138.         {   //check against every room that was placed before
  139.             if (CheckOverlap(existingRoom, newRoom) || newRoom.x < 0 || newRoom.y < 0) //can't overlap or be negative
  140.             {
  141.                 invalid = true;
  142.                 break;
  143.             }
  144.         }
  145.  
  146.         if (invalid)
  147.             return false;
  148.         else
  149.         {
  150.             //Add the room to the Room List, create a floor prefab, parent it
  151.             //and create a mesh using the floorData
  152.            
  153.             GameObject roomObject = Sys.LoadPrefab("Prefabs/floor_prefab");
  154.             roomObject.transform.position = new Vector3(newRoom.x, newRoom.y, GameState.FLOOR_Z_DEPTH);
  155.             roomObject.transform.SetParent(_dunLevel.floorParent);        //set the parent of newRoom to be dungeon
  156.             FloorMesh floorMesh = roomObject.GetComponent<FloorMesh>();
  157.             floorMesh.GenerateMesh(newRoom);                             //create the floor mesh of newRoom
  158.  
  159.             _dunLevel.meshList.Add(floorMesh);
  160.             _dunLevel.roomList.Add(newRoom);
  161.             //create a door or opening, based on this generators doorChance
  162.             if (Random.Range(0, 101) < this.doorChance)
  163.                 CreateRandomDoor(startRoom, newRoom);
  164.             else
  165.                 CreateOpening(startRoom, newRoom);
  166.  
  167.             return true;
  168.         }
  169.     }
  170.  
  171.     //  Place walls bordering rooms.
  172.     protected void AddWallsToRooms()
  173.     {
  174.        
  175.         foreach (FloorData room in _dunLevel.roomList)
  176.         {
  177.             for (int i = 0; i < room.height; i++) //iterate over the East/West walls.
  178.             {
  179.                 CreateWall(room.x - 1, room.y + i); //make west wall
  180.                 CreateWall(room.x + room.width, room.y + i); //make east wall
  181.             }
  182.  
  183.             for (int j = 0; j < room.width + 2; j++)//iterate the North/South walls, which are sandwiched between the EastWest walls.
  184.             {
  185.                 CreateWall(room.x - 1 + j, room.y - 1); //make south wall
  186.                 CreateWall(room.x - 1 + j, room.y + room.height); //make south wall
  187.             }
  188.  
  189.         }
  190.     }
  191.  
  192.     protected void RemoveOverlappingWalls()
  193.     {
  194.         foreach (FloorData door in _dunLevel.entryList)
  195.         {
  196.             for (int y = 0; y < door.height; y++)
  197.             {
  198.                 for (int x = 0; x < door.width; x++)
  199.                 {
  200.                     _dunLevel.DestroyEntity(door.x + x, door.y + y);
  201.                 }
  202.             }
  203.         }
  204.     }
  205.  
  206.     //Note, normally it'd be width or height minus one, however I want a 1 tile gap between rooms minimum.
  207.     public static bool CheckOverlap(FloorData roomA, FloorData roomB)
  208.     {
  209.         //if the left side of the room is past the right side of the other room, there's no overlap
  210.         if (roomA.x > (roomB.x + roomB.width) || roomB.x > roomA.x + roomA.width)
  211.             return false;
  212.  
  213.         //if the bottom of the room is above the top of the other room, there's no overlap
  214.         if (roomA.y > (roomB.y + roomB.height) || roomB.y > roomA.y + roomA.height)
  215.             return false;
  216.  
  217.         return true;
  218.     }
  219.  
  220.     #endregion Dungeon Generation Helpers
Advertisement
Add Comment
Please, Sign In to add comment