Exemplo n.º 1
0
    void SetTileMaterial(E_TileMaterialType tileMaterialType, out Transform[] floorTiles, out Transform[] wallTiles)
    {
        switch (tileMaterialType)
        {
        case E_TileMaterialType.dirt:
            floorTiles = tile_dirt_floor;
            wallTiles  = tile_dirt_wall;
            break;

        default:
            floorTiles = tile_dirt_floor;
            wallTiles  = tile_dirt_wall;
            break;
        }
    }
Exemplo n.º 2
0
    //create a room from a startpoint(leftdown), width, and length
    bool CreateRoom(int startX,
                    int startZ,
                    int extendX,
                    int extendZ,
                    E_RoomType roomType,
                    E_TileMaterialType tileMaterialType)
    {
        if (extendX <= 1 || extendZ <= 1)      //room has wall so it need enough size
        {
            return(false);
        }
        if (startX + extendX > dungeonWidth || startZ + extendZ > dungeonLength || startX < 0 || startZ < 0)
        {
            return(false);           // out of the dungeon bound
        }
        //enough space in case of wall thickness
        for (int i = -1; i < extendX + 1; i++)
        {
            for (int j = -1; j < extendZ + 1; j++)
            {
                if (startX + i < 0 ||
                    startX + i > layerTile.GetLength(0) - 1 ||
                    startZ + j < 0 ||
                    startZ + j > layerTile.GetLength(1) - 1)
                {
                    return(false);                   //防止数组越界
                }
                if (layerTile[startX + i, startZ + j] != E_TileType.empty)
                {
                    return(false);                   //not enough space for room
                }
            }
        }

        //material type
        Transform[] floorTiles, wallTiles;
        SetTileMaterial(tileMaterialType, out floorTiles, out wallTiles);

        //generate room root
        MapElement currentRoomScript = GenerateElementRoot(E_MapElementType.Room, startX, startZ);

        currentRoomScript.tile    = new Transform[extendX, extendZ];
        currentRoomScript.hasItem = new bool[extendX, extendZ];
        currentRoomScript.walls   = new List <Transform>();
        for (int i = 0; i < extendX; i++)
        {
            for (int j = 0; j < extendZ; j++)
            {
                currentRoomScript.tile[i, j]    = RandomlyCreateTile(i, j, floorTiles);
                currentRoomScript.hasItem[i, j] = false;
                if (i + j == 0)
                {
                    //corner leftdown
                    layerTile[startX + i, startZ + j] = E_TileType.corner_LeftDown;
                    RandomlyCreateWall(i, j, wallTiles, E_Direction.Left, currentRoomScript.walls);
                    RandomlyCreateWall(i, j, wallTiles, E_Direction.Down, currentRoomScript.walls);
                }
                else if (i + j == extendX + extendZ - 2)
                {
                    //corner rightup
                    layerTile[startX + i, startZ + j] = E_TileType.corner_RightUp;
                    RandomlyCreateWall(i, j, wallTiles, E_Direction.Right, currentRoomScript.walls);
                    RandomlyCreateWall(i, j, wallTiles, E_Direction.Up, currentRoomScript.walls);
                }
                else if (i - j == extendX - 1)
                {
                    //corner rightdown
                    layerTile[startX + i, startZ + j] = E_TileType.corner_RightDown;
                    RandomlyCreateWall(i, j, wallTiles, E_Direction.Right, currentRoomScript.walls);
                    RandomlyCreateWall(i, j, wallTiles, E_Direction.Down, currentRoomScript.walls);
                }
                else if (j - i == extendZ - 1)
                {
                    //corner leftup
                    layerTile[startX + i, startZ + j] = E_TileType.corner_LeftUp;
                    RandomlyCreateWall(i, j, wallTiles, E_Direction.Left, currentRoomScript.walls);
                    RandomlyCreateWall(i, j, wallTiles, E_Direction.Up, currentRoomScript.walls);
                }
                else if (i == 0)
                {
                    //wall left
                    layerTile[startX + i, startZ + j] = E_TileType.wall_left;
                    RandomlyCreateWall(i, j, wallTiles, E_Direction.Left, currentRoomScript.walls);
                }
                else if (j == 0)
                {
                    //wall down
                    layerTile[startX + i, startZ + j] = E_TileType.wall_down;
                    RandomlyCreateWall(i, j, wallTiles, E_Direction.Down, currentRoomScript.walls);
                }
                else if (i == extendX - 1)
                {
                    //wall right
                    layerTile[startX + i, startZ + j] = E_TileType.wall_right;
                    RandomlyCreateWall(i, j, wallTiles, E_Direction.Right, currentRoomScript.walls);
                }
                else if (j == extendZ - 1)
                {
                    //wall up
                    layerTile[startX + i, startZ + j] = E_TileType.wall_up;
                    RandomlyCreateWall(i, j, wallTiles, E_Direction.Up, currentRoomScript.walls);
                }
                else
                {
                    //floor
                    layerTile[startX + i, startZ + j] = E_TileType.floor;
                }
            }
        }
        currentRoomScript.exitCount = 0;
        currentRoomScript.roomType  = roomType;

//		switch (roomType) {
//		case E_RoomType.normal:
//
//			break;
//		default:
//			break;
//		}

        return(true);
    }
Exemplo n.º 3
0
    bool CreateCorridorFromMapElement(Transform mapElem, E_TileMaterialType tileMaterialType, int index = -1)
    {
        List <Transform> chosenWalls = mapElem.GetComponent <MapElement> ().walls;
        Transform        testedWall;

        if (index == -1)
        {
            testedWall = chosenWalls[Random.Range(0, chosenWalls.Count - 1)];
        }
        else
        {
            testedWall = chosenWalls[index];
        }

        int wallX = Mathf.RoundToInt(testedWall.position.x) / tileWidth;
        int wallZ = Mathf.RoundToInt(testedWall.position.z) / tileWidth;
        int corridorStartX, corridorStartZ;

        //如果处于房间拐角则不能创建
        if (layerTile[wallX, wallZ] == E_TileType.corner_LeftDown ||
            layerTile[wallX, wallZ] == E_TileType.corner_LeftUp ||
            layerTile[wallX, wallZ] == E_TileType.corner_RightDown ||
            layerTile[wallX, wallZ] == E_TileType.corner_RightUp)
        {
            return(false);
        }

        E_Direction WallDir = CheckWallDirection(testedWall);

        //corridor direction
        if (WallDir == E_Direction.Unset)
        {
            return(false);
        }
        switch (WallDir)
        {
        case E_Direction.Up:
            corridorStartX = wallX;
            corridorStartZ = wallZ + 1;
            break;

        case E_Direction.Down:
            corridorStartX = wallX;
            corridorStartZ = wallZ - 1;
            break;

        case E_Direction.Left:
            corridorStartX = wallX - 1;
            corridorStartZ = wallZ;
            break;

        case E_Direction.Right:
            corridorStartX = wallX + 1;
            corridorStartZ = wallZ;
            break;

        default:
            corridorStartX = wallX;
            corridorStartZ = wallZ;
            return(false);
        }
        //random corridor length
        int corridorLength = Random.Range(minCorridorLength, maxCorridorLength);

        if (CreateCorridor(corridorStartX, corridorStartZ, corridorLength, WallDir, tileMaterialType))
        {
            mapElem.GetComponent <MapElement>().exitCount++;
            chosenWalls.Remove(testedWall);
            //新建立的corridor将保存被隐藏的wall
            layerCorridors[layerCorridors.Count - 1].GetComponent <MapElement>().removedWall = testedWall;
            testedWall.gameObject.SetActive(false);
            return(true);
        }
        else
        {
            return(false);
        }
    }
Exemplo n.º 4
0
    //create a corridor from a startpoint and dir
    bool CreateCorridor(int corridorStartX, int corridorStartZ, int corridorLength, E_Direction corridorDir, E_TileMaterialType tileMaterialType)
    {
        int corridorDirDeltaX, corridorDirDeltaZ;

        if (corridorDir == E_Direction.Unset)
        {
            return(false);
        }
        switch (corridorDir)
        {
        case E_Direction.Up:
            corridorDirDeltaX = 0;
            corridorDirDeltaZ = 1;
            break;

        case E_Direction.Down:
            corridorDirDeltaX = 0;
            corridorDirDeltaZ = -1;
            break;

        case E_Direction.Left:
            corridorDirDeltaX = -1;
            corridorDirDeltaZ = 0;
            break;

        case E_Direction.Right:
            corridorDirDeltaX = 1;
            corridorDirDeltaZ = 0;
            break;

        default:
            corridorDirDeltaX = 0;
            corridorDirDeltaZ = 0;
            return(false);
        }

        for (int i = 0; i < corridorLength + 1; i++)
        {
            //check for enough space
            switch (corridorDir)
            {
            case E_Direction.Up:
                if (corridorStartX - 1 < 0 ||
                    corridorStartX + 1 > layerTile.GetLength(0) - 1 ||
                    corridorStartZ + i < 0 ||
                    corridorStartZ + i > layerTile.GetLength(1) - 1)
                {
                    return(false);
                }
                if (layerTile[corridorStartX, corridorStartZ + i] != E_TileType.empty ||
                    layerTile[corridorStartX + 1, corridorStartZ + i] != E_TileType.empty ||
                    layerTile[corridorStartX - 1, corridorStartZ + i] != E_TileType.empty)
                {
                    return(false);
                }
                break;

            case E_Direction.Down:
                if (corridorStartX - 1 < 0 ||
                    corridorStartX + 1 > layerTile.GetLength(0) - 1 ||
                    corridorStartZ - i < 0 ||
                    corridorStartZ - i > layerTile.GetLength(1) - 1)
                {
                    return(false);
                }
                if (layerTile[corridorStartX, corridorStartZ - i] != E_TileType.empty ||
                    layerTile[corridorStartX + 1, corridorStartZ - i] != E_TileType.empty ||
                    layerTile[corridorStartX - 1, corridorStartZ - i] != E_TileType.empty)
                {
                    return(false);
                }
                break;

            case E_Direction.Left:
                if (corridorStartX - i < 0 ||
                    corridorStartX - i > layerTile.GetLength(0) - 1 ||
                    corridorStartZ - 1 < 0 ||
                    corridorStartZ + 1 > layerTile.GetLength(1) - 1)
                {
                    return(false);
                }
                if (layerTile[corridorStartX - i, corridorStartZ] != E_TileType.empty ||
                    layerTile[corridorStartX - i, corridorStartZ + 1] != E_TileType.empty ||
                    layerTile[corridorStartX - i, corridorStartZ - 1] != E_TileType.empty)
                {
                    return(false);
                }
                break;

            case E_Direction.Right:
                if (corridorStartX + i < 0 ||
                    corridorStartX + i > layerTile.GetLength(0) - 1 ||
                    corridorStartZ - 1 < 0 ||
                    corridorStartZ + 1 > layerTile.GetLength(1) - 1)
                {
                    return(false);
                }
                if (layerTile[corridorStartX + i, corridorStartZ] != E_TileType.empty ||
                    layerTile[corridorStartX + i, corridorStartZ + 1] != E_TileType.empty ||
                    layerTile[corridorStartX + i, corridorStartZ - 1] != E_TileType.empty)
                {
                    return(false);
                }
                break;

            default:
                break;
            }
        }

        //material type
        Transform[] floorTiles, wallTiles;
        SetTileMaterial(tileMaterialType, out floorTiles, out wallTiles);

        //generate corridor root
        MapElement currentCorridorScript = GenerateElementRoot(E_MapElementType.Corridor, corridorStartX, corridorStartZ);

        currentCorridorScript.startX = corridorStartX;
        currentCorridorScript.startZ = corridorStartZ;
        currentCorridorScript.dirX   = corridorDirDeltaX;
        currentCorridorScript.dirZ   = corridorDirDeltaZ;

        //generate tiles
        currentCorridorScript.tileSingle = new Transform[corridorLength];
        currentCorridorScript.walls      = new List <Transform> ();
        for (int i = 0; i < corridorLength; i++)
        {
            currentCorridorScript.tileSingle[i] = RandomlyCreateTile(corridorDirDeltaX * i, corridorDirDeltaZ * i, floorTiles);
            if (corridorDirDeltaX == 0)
            {
                layerTile[corridorStartX, corridorStartZ + corridorDirDeltaZ * i] = E_TileType.corridor_Vertical;
                RandomlyCreateWall(corridorDirDeltaX * i, corridorDirDeltaZ * i, wallTiles, E_Direction.Left, currentCorridorScript.walls);
                RandomlyCreateWall(corridorDirDeltaX * i, corridorDirDeltaZ * i, wallTiles, E_Direction.Right, currentCorridorScript.walls);
            }
            else
            {
                layerTile[corridorStartX + corridorDirDeltaX * i, corridorStartZ] = E_TileType.corridor_Horizontal;
                RandomlyCreateWall(corridorDirDeltaX * i, corridorDirDeltaZ * i, wallTiles, E_Direction.Up, currentCorridorScript.walls);
                RandomlyCreateWall(corridorDirDeltaX * i, corridorDirDeltaZ * i, wallTiles, E_Direction.Down, currentCorridorScript.walls);
            }
            //corridor end wall
            if (i == corridorLength - 1)
            {
                RandomlyCreateWall(corridorDirDeltaX * i, corridorDirDeltaZ * i, wallTiles, corridorDir, currentCorridorScript.walls);
            }
        }
        //corridor is created with a exit (beginning)
        currentCorridorScript.exitCount = 1;
        return(true);
    }
Exemplo n.º 5
0
    //generate a room from a wall on its dir
    bool CreateRoomFromMapElement(Transform mapElem, E_RoomType roomType, E_TileMaterialType tileMaterialType, int index = -1)
    {
        List <Transform> chosenWalls = mapElem.GetComponent <MapElement> ().walls;
        Transform        testedWall;

        if (index == -1)
        {
            testedWall = chosenWalls[Random.Range(0, chosenWalls.Count - 1)];
        }
        else
        {
            testedWall = chosenWalls[index];
        }

        int         wallX = Mathf.RoundToInt(testedWall.position.x) / tileWidth;
        int         wallZ = Mathf.RoundToInt(testedWall.position.z) / tileWidth;
        int         deltaX, deltaZ;
        E_Direction WallDir = CheckWallDirection(testedWall);

        //corridor direction
        if (WallDir == E_Direction.Unset)
        {
            return(false);
        }
        switch (WallDir)
        {
        case E_Direction.Up:
            deltaX = 0;
            deltaZ = 1;
            break;

        case E_Direction.Down:
            deltaX = 0;
            deltaZ = -1;
            break;

        case E_Direction.Left:
            deltaX = -1;
            deltaZ = 0;
            break;

        case E_Direction.Right:
            deltaX = 1;
            deltaZ = 0;
            break;

        default:
            deltaX = 0;
            deltaZ = 0;
            return(false);
        }

        int roomWidth = Random.Range(minRoomWidth, maxRoomWidth);
        int roomLength = Random.Range(minRoomLength, maxRoomLength);
        int roomStartX, roomStartZ, doorDistance;

        //calculate room startpos and doorpos 根据门离两边的距离算出房间的起始位置
        if (deltaX == 0)
        {
            doorDistance = Random.Range(1, roomWidth - 2);           //避开房间拐角
            roomStartX   = wallX - doorDistance;
            if (deltaZ == 1)
            {
                roomStartZ = wallZ + deltaZ;
            }
            else
            {
                roomStartZ = wallZ + deltaZ * roomLength;
            }
        }
        else
        {
            doorDistance = Random.Range(1, roomLength - 2);
            roomStartZ   = wallZ - doorDistance;
            if (deltaX == 1)
            {
                roomStartX = wallX + deltaX;
            }
            else
            {
                roomStartX = wallX + deltaX * roomWidth;
            }
        }
        //calculate a small entrance corridor space and offset roompos
        //random corridor length
        int corridorEntranceLength = Random.Range(1, 7);
        int corridorStartX         = wallX + deltaX;
        int corridorStartZ         = wallZ + deltaZ;

        //offset room
        roomStartX += deltaX * corridorEntranceLength;
        roomStartZ += deltaZ * corridorEntranceLength;

        //material type
        Transform[] floorTiles, wallTiles;
        SetTileMaterial(tileMaterialType, out floorTiles, out wallTiles);

        //create room entrance corridor
        if (CreateCorridor(corridorStartX, corridorStartZ, corridorEntranceLength, WallDir, tileMaterialType))
        {
            layerCorridors[layerCorridors.Count - 1].GetComponent <MapElement>().removedWall =
                RemoveWallFromMapElement(wallX + deltaX * corridorEntranceLength,
                                         wallZ + deltaZ * corridorEntranceLength,
                                         deltaX,
                                         deltaZ,
                                         layerCorridors[layerCorridors.Count - 1].GetComponent <MapElement>());
        }
        else
        {
            return(false);
        }

        //为了使房间能顺利建立将入口处layerTile临时替换为empty
        E_TileType tmpTileType = layerTile [wallX + deltaX * corridorEntranceLength, wallZ + deltaZ * corridorEntranceLength];

        layerTile [wallX + deltaX * corridorEntranceLength, wallZ + deltaZ * corridorEntranceLength] = E_TileType.empty;

        //create room
        if (CreateRoom(roomStartX, roomStartZ, roomWidth, roomLength, roomType, tileMaterialType))
        {
            RemoveWallFromMapElement(wallX + deltaX * (corridorEntranceLength + 1),
                                     wallZ + deltaZ * (corridorEntranceLength + 1),
                                     -deltaX,
                                     -deltaZ,
                                     layerRooms[layerRooms.Count - 1].GetComponent <MapElement>());
        }
        else
        {
            GameObject recentCorridorGO = layerCorridors[layerCorridors.Count - 1].gameObject;
            CancelRecentMapElement(E_MapElementType.Corridor, recentCorridorGO);
            return(false);
        }
        //入口处恢复
        layerTile [wallX + deltaX * corridorEntranceLength, wallZ + deltaZ * corridorEntranceLength] = tmpTileType;

        mapElem.GetComponent <MapElement>().exitCount++;
        chosenWalls.Remove(testedWall);
        Destroy(testedWall.gameObject);
        return(true);
    }