//Genera l'intero dungeon, il paramentro dungeon container è un semplice empty game object di contenimento, minshiftValue è il valore di spostamento //utilizzato dall'algoritmo di piazzamento delle stanze public void Generate(int minWidth, int maxWidth, int minHeight, int maxHeight, int roomNum, Dungeon dungeonContainer, int minShitValue) { //questo array serve per memorizzare i dati delle stanze //le stanze non vengono fisicamente allocate ma servono solo per l'algoritmo di piazzamento DungeonRoom[] roomArray = new DungeonRoom[roomNum]; corridorsGO = new GameObject("corridors"); //algoritmo di separazione for (int i = 0; i < roomNum; i++) { roomArray[i] = new DungeonRoom(minWidth, maxWidth, minHeight, maxHeight); roomArray[i].Data.Origin = new IntVector2(0, 0);//l'origine delle stanze è sempre dal punto 0,0 roomArray[i].Data.Name = "Room: " + i; while (tileMatrix.checkOverLap(roomArray[i].Data.Origin, roomArray[i].Data.Width, roomArray[i].Data.Height)) { int dir = Random.Range(0, 2); if (dir == 0)//muovo in orizzontale { roomArray[i].moveRoom(minShitValue, 0); } else if (dir == 1) //muovo in verticale { roomArray[i].moveRoom(0, minShitValue); } } updateTileMatrix(roomArray[i]); }//fine algoritmo di separazione //comincia la creazione delle stanze nello spazio 3D DungeonRoom[] gameObjectRoomArray = new DungeonRoom[roomNum];//queste invece vengono effettivamente allocate for (int i = 0; i < roomNum; i++) { gameObjectRoomArray[i] = Instantiate(dungeonRoomPrefab) as DungeonRoom; gameObjectRoomArray[i].transform.parent = dungeonContainer.transform; gameObjectRoomArray[i].generateRoom(roomArray[i]); gameObjectRoomArray[i].Data.Name = roomArray[i].Data.Name; gameObjectRoomArray[i].name = gameObjectRoomArray[i].Data.Name; gameObjectRoomArray[i].transform.localPosition = new Vector3(roomArray[i].Data.Origin.x, 0, roomArray[i].Data.Origin.z); gameObjectRoomArray[i].AllocateRoomInSpace(); updateDungeonActiveCells(roomArray[i].Data.Origin, gameObjectRoomArray[i]);//utilizzo un dizionario per mantenermi le mattonelle attive all'interno del dungeon corridoi + stanze } //algoritmo di connessione O(n^3), crea prima il gravo RNG e poi connette le stanze con percorsi rettangolari int ijDist, ikDist, jkDist; bool skip = false; for (int i = 0; i < roomNum; i++) { for (int j = i + 1; j < roomNum; j++) { skip = false; ijDist = roomArray[i].distance(roomArray[j]); //per ogni coppia di stanze (i,j) controllo che non esista un terzo nodo k t.c Mathf.Max(ikDist, jkDist) < ijDist //se esiste break dal questo for e quindi significa che non esiste l'arco i,j for (int k = 0; k < roomNum; k++) { if (k == i || k == j) { continue; } ikDist = roomArray[i].distance(roomArray[k]); jkDist = roomArray[j].distance(roomArray[k]); if (Mathf.Max(ikDist, jkDist) < ijDist) { skip = true; break; } } if (!skip) {//se la prima coppia scelta i,j non è stata scartata vuol dire che il suo arco può essere aggiunto al grafo Gizmos.color = Color.blue; Vector3 c1 = new Vector3(roomArray[i].Data.Center.x, 3, roomArray[i].Data.Center.z); Vector3 c2 = new Vector3(roomArray[j].Data.Center.x, 3, roomArray[j].Data.Center.z); centerList.Add(new centerPair(c1, c2)); //serve per disegnare il grafo rosso di overlay //ora quindi si crea il corridoio tra i e j createCorridor(corridorsGO, gameObjectRoomArray[i], gameObjectRoomArray[j]); // va passato il gameobject istanziato nello spazio e non il roomArray[i] corridorsGO.transform.parent = transform; //print("ROOM " + gameObjectRoomArray[i] + " --- connected to ROOM --- " + gameObjectRoomArray[j]); } } }//fine algoritmo di connessione //foreach (KeyValuePair<IntVector2, DungeonCell> entry in activeDungeonCells) //{ // print("key: " + entry.Key + ", value: " + entry.Value); //} print(tileMatrix); } //fine generate