示例#1
0
    //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