private void removeRoomAt(int posX, int posY)
    {
        int l = map.Count;

        for (int i = 0; i < l; i++)
        {
            if (map[i].genPosX == posX && map[i].genPosY == posY)
            {
#if UNITY_EDITOR
                GameObject.DestroyImmediate(map[i].gameObject);
#else
                GameObject.Destroy(map[i].gameObject);
#endif
                MGMazeRoom[] neighbors = new MGMazeRoom[4] {
                    getRoomAt(posX, posY + 1), getRoomAt(posX + 1, posY), getRoomAt(posX, posY - 1), getRoomAt(posX - 1, posY)
                };
                foreach (MGMazeRoom neib in neighbors)
                {
                    if (neib != null)
                    {
                        neib.attached--;
                    }
                }
                map.RemoveAt(i); i--;
            }
        }
    }
 private int entranceAt(MGMazeRoom r, int dir)
 {
     if (r == null)
     {
         return(0);
     }
     return(r.HasDirection(dir) ? 1 : 2);
 }
예제 #3
0
    private void OnEnable()
    {
        GameObject      generatorObj = GameObject.Find("MazeGenerator") as GameObject;
        MGMazeGenerator generator    = generatorObj.GetComponent <MGMazeGenerator>();

        MGMazeRoom mzr = (MGMazeRoom)target;


        mzr.width = generator.roomWallLength;
        mzr.depth = generator.roomWallLength;
    }
    private bool putDoor(MGMazeRoom room, int dir)
    {
        int dPosX = room.genPosX * 2, dPosY = room.genPosY * 2;

        switch (dir)
        {
        case 0: dPosY++;
            break;

        case 1: dPosX++;
            break;

        case 2: dPosY--;
            break;

        case 3: dPosX--;
            break;
        }

        foreach (MGDoor door in doormap)
        {
            if (door.posX == dPosX && door.posY == dPosY)
            {
                return(false);
            }
        }

        GameObject obj  = GameObject.Instantiate(doors[Random.Range(0, doors.Count)].gameObject, new Vector3(dPosX * roomWallLength / 2f, 0, dPosY * roomWallLength / 2f), Quaternion.identity) as GameObject;
        MGDoor     dObj = obj.GetComponent <MGDoor>();

        dObj.posY = dPosY;
        dObj.posX = dPosX;
        doormap.Add(dObj);
        obj.name = "Door @ " + dPosX + ":" + dPosY;
        if ((dir % 2 == 0) ^ dObj.north_SouthOrentation)
        {
            dObj.rotated = true;
            obj.transform.Rotate(Vector3.up * -90f);
        }

        return(true);
    }
    private bool putRoomAt(int posX, int posY, bool deadEnd = false)
    {
        shuffleIndexes();
        MGMazeRoom[] neighbors = new MGMazeRoom[4] {
            getRoomAt(posX, posY + 1), getRoomAt(posX + 1, posY), getRoomAt(posX, posY - 1), getRoomAt(posX - 1, posY)
        };
        int[] entrances = new int[4] {
            entranceAt(neighbors[0], 2),
            entranceAt(neighbors[1], 3),
            entranceAt(neighbors[2], 0),
            entranceAt(neighbors[3], 1)
        };

        if (deadEnd)
        {
            for (int i = 0; i < 4; i++)
            {
                if (entrances[i] == 0)
                {
                    entrances[i] = 2;
                }
            }
        }
        int openEnds = 0;

        for (int i = 0; i < map.Count; i++)
        {
            openEnds += map[i].openEnds;
        }


        int minDistance = -1;

        foreach (MGMazeRoom r in neighbors)
        {
            if (r != null && (r.distance < minDistance || minDistance == -1))
            {
                minDistance = r.distance;
            }
        }

        int  roomAdd   = Random.Range(0, rooms.Count);
        bool putFinish = (minDistance >= minDistanceToFinish || roomsCountToGenerate <= map.Count) && !finishPut;

        for (int i = 0; i <= rooms.Count; i++)
        {
            roomAdd = indexes[i % rooms.Count];
            MGMazeRoom roomToAdd = putFinish ? finishRoom : rooms[roomAdd];

            int closedEnds = 0;
            foreach (int e in entrances)
            {
                if (e == 1)
                {
                    closedEnds++;
                }
            }

            if (map.Count < 3 && roomToAdd.exits <= 2)
            {
                roomAdd++; putFinish = false; continue;
            }
            if (!deadEnd && closedEnds >= openEnds && roomsCountToGenerate > map.Count && roomToAdd.exits <= closedEnds)
            {
                roomAdd++; putFinish = false; continue;
            }

            if (
                (putFinish && ((openEnds < 3 && map.Count < roomsCountToGenerate) || minDistance < minDistanceToFinish || finishPut)) ||
                (!putFinish && rooms[roomAdd].exits == 1 && openEnds < 3 && !deadEnd)
                )
            {
                roomAdd++; putFinish = false; continue;
            }



            // try to fit
            int rotation = 0;
            if (roomToAdd.fitsMask(entrances, out rotation))
            {
                if (putFinish)
                {
                    finishPut = true;
                }
                GameObject go = GameObject.Instantiate(roomToAdd.gameObject, new Vector3(posX * roomWallLength, 0, posY * roomWallLength), Quaternion.identity) as GameObject;
                go.transform.Rotate(Vector3.up * -90f * rotation);

                MGMazeRoom mr = go.GetComponent <MGMazeRoom>();

                mr.genPosX  = posX;
                mr.genPosY  = posY;
                mr.rotated  = rotation;
                mr.distance = -1;
                for (int ni = 0; ni < 4; ni++)
                {
                    MGMazeRoom r = neighbors[ni];
                    if (r != null && (r.distance < mr.distance || mr.distance == -1))
                    {
                        mr.distance = r.distance + 1;
                    }
                    if (r != null && entrances[ni] == 1)
                    {
                        r.attached++; mr.attached++;
                    }
                }

                go.name = (putFinish ? "finish" : "room") + "dist:" + mr.distance + "@" + posX + ":" + posY + " rot:" + rotation + " ends:" + openEnds;

                map.Add(mr);
                return(true);
            }
            putFinish = false;
            roomAdd++;
        }

        return(false);
    }