/// <summary>
    /// 最初の区画を作る
    /// </summary>
    /// <param name = "left"  >左</param>
    /// <param name = "top"   >上</param>
    /// <param name = "right" >右</param>
    /// <param name = "bottom">下</param>
    void Create_Division(int left, int top, int right, int bottom)
    {
        Dungeon_Division div = new Dungeon_Division();

        div.Outer.Set_Position(left, top, right, bottom);
        division_list.Add(div);
    }
    /// <summary>
    /// 部屋同士を通路でつなぐ
    /// </summary>
    void Connect_Rooms()
    {
        for (int i = 0; i < division_list.Count - 1; i++)
        {
            // リストの前後の区画は必ず接続できる
            Dungeon_Division a = division_list[i];
            Dungeon_Division b = division_list[i + 1];

            // 2つの部屋をつなぐ通路を作成
            Create_Road(a, b);

            // 孫にも接続する
            for (int j = i + 2; j < division_list.Count; j++)
            {
                Dungeon_Division c = division_list[j];
                if (Create_Road(a, c, true))
                {
                    // 孫に接続できたらおしまい
                    break;
                }
            }
        }
    }
    /// <summary>
    /// 指定した部屋の間を通路でつなぎ、部屋に隣接している通路を入口とする
    /// </summary>
    /// <param name="division_A">部屋1</param>
    /// <param name="division_B">部屋2</param>
    /// <param name="grand_child">孫チェックするかどうか</param>
    /// <returns>つなぐことができたらtrue</returns>
    bool Create_Road(Dungeon_Division division_A, Dungeon_Division division_B, bool grand_child = false)
    {
        // 上下でつながっている
        if (division_A.Outer.Bottom == division_B.Outer.Top || division_A.Outer.Top == division_B.Outer.Bottom)
        {
            // 部屋から伸ばす通路の開始位置を決める
            int x1 = Random.Range(division_A.Room.Left, division_A.Room.Right);
            int x2 = Random.Range(division_B.Room.Left, division_B.Room.Right);
            int y  = 0;

            if (grand_child)
            {
                // すでに通路が存在していたらその情報を使用する
                if (division_A.Has_Road())
                {
                    x1 = division_A.Road.Left;
                }
                if (division_B.Has_Road())
                {
                    x2 = division_B.Road.Left;
                }
            }

            // A
            // |
            // B (Aが上側)
            if (division_A.Outer.Top > division_B.Outer.Top)
            {
                y = division_A.Outer.Top;
                // 通路を作成
                division_B.Create_Road(x2, division_B.Room.Bottom + Define_Value.TILE_SCALE, x2 + Define_Value.TILE_SCALE, y);
                // 通路を作成
                division_A.Create_Road(x1, y + Define_Value.TILE_SCALE, x1 + Define_Value.TILE_SCALE, division_A.Room.Top - Define_Value.TILE_SCALE);

                // 入口の座標を保持
                entrance_position = new Vector2Int(x2, division_B.Room.Bottom);
                entrance_positions.Add(entrance_position);
                entrance_position = new Vector2Int(x1, division_A.Room.Top - Define_Value.ROOM_FLAME);
                entrance_positions.Add(entrance_position);
            }
            // B
            // |
            // A (Bが上側)
            else
            {
                y = division_B.Outer.Top;
                // 通路を作成
                division_A.Create_Road(x1, division_A.Room.Bottom + Define_Value.TILE_SCALE, x1 + Define_Value.TILE_SCALE, y);
                // 通路を作成
                division_B.Create_Road(x2, y, x2 + Define_Value.TILE_SCALE, division_B.Room.Top - Define_Value.TILE_SCALE);

                // 入口の座標を保持
                entrance_position = new Vector2Int(x1, division_A.Room.Bottom);
                entrance_positions.Add(entrance_position);
                entrance_position = new Vector2Int(x2, division_B.Room.Top - Define_Value.ROOM_FLAME);
                entrance_positions.Add(entrance_position);
            }

            Fill_Dungeon_Rectangle_Road(division_A.Road);
            Fill_Dungeon_Rectangle_Road(division_B.Road);

            // 通路同士を接続する
            Fill_Horizontal_Line(x1, x2, y);

            // 通路を作れた
            return(true);
        }

        // 左右でつながっている
        if (division_A.Outer.Left == division_B.Outer.Right || division_A.Outer.Right == division_B.Outer.Left)
        {
            // 部屋から伸ばす通路の開始位置を決める
            int y1 = Random.Range(division_A.Room.Top, division_A.Room.Bottom);
            int y2 = Random.Range(division_B.Room.Top, division_B.Room.Bottom);
            int x  = 0;

            if (grand_child)
            {
                // すでに通路が存在していたらその情報を使う
                if (division_A.Has_Road())
                {
                    y1 = division_A.Road.Top;
                }
                if (division_B.Has_Road())
                {
                    y2 = division_B.Road.Top;
                }
            }

            // B - A (Bが左側)
            if (division_A.Outer.Left > division_B.Outer.Left)
            {
                x = division_A.Outer.Left;
                // 通路を作成
                division_B.Create_Road(division_B.Room.Right + Define_Value.TILE_SCALE, y2, x, y2 + Define_Value.TILE_SCALE);
                // 通路を作成
                division_A.Create_Road(x + Define_Value.TILE_SCALE, y1, division_A.Room.Left - Define_Value.TILE_SCALE, y1 + Define_Value.TILE_SCALE);

                // 入口の座標を保持
                entrance_position = new Vector2Int(division_B.Room.Right, y2);
                entrance_positions.Add(entrance_position);
                entrance_position = new Vector2Int(division_A.Room.Left - Define_Value.ROOM_FLAME, y1);
                entrance_positions.Add(entrance_position);
            }
            // A - B (Aが左側)
            else
            {
                x = division_B.Outer.Left;
                // 通路を作成
                division_A.Create_Road(division_A.Room.Right + Define_Value.TILE_SCALE, y1, x, y1 + Define_Value.TILE_SCALE);
                // 通路を作成
                division_B.Create_Road(x, y2, division_B.Room.Left - Define_Value.TILE_SCALE, y2 + Define_Value.TILE_SCALE);

                // 入口の座標を保持
                entrance_position = new Vector2Int(division_A.Room.Right, y1);
                entrance_positions.Add(entrance_position);
                entrance_position = new Vector2Int(division_B.Room.Left - Define_Value.ROOM_FLAME, y2);
                entrance_positions.Add(entrance_position);
            }

            Fill_Dungeon_Rectangle_Road(division_A.Road);
            Fill_Dungeon_Rectangle_Road(division_B.Road);

            // 通路同士を接続する
            Fill_Virtical_Line(y1, y2, x);

            // 通路を作れた
            return(true);
        }
        // つなげなかった
        return(false);
    }
    /// <summary>
    /// 区画を分割する
    /// </summary>
    /// <param name="is_vertical">垂直分割するかどうか</param>
    void Split_Divison(bool is_vertical)
    {
        // 末尾の要素を取り出し
        Dungeon_Division parent = division_list[division_list.Count - 1];

        division_list.Remove(parent);

        // 子となる区画を生成
        Dungeon_Division child = new Dungeon_Division();

        if (is_vertical)
        {
            // 縦方向に分割する
            if (Check_Division_Size(parent.Outer.Height) == false)
            {
                // 縦の高さが足りない
                // 親区画を戻しておしまい
                division_list.Add(parent);
                return;
            }

            // 分割ポイントを求める
            int a = parent.Outer.Top + (Define_Value.MIN_ROOM + Define_Value.MERGIN_SIZE);
            int b = parent.Outer.Bottom - (Define_Value.MIN_ROOM + Define_Value.MERGIN_SIZE);

            // AB間の距離を求める
            int ab = b - a;

            // 最大の部屋サイズを超えないようにする
            ab = Mathf.Min(ab, Define_Value.MAX_ROOM);

            // 分割点を決める
            int p = a + Random.Range(0, ab + 1);

            // 子区画に情報を設定
            child.Outer.Set_Position(
                parent.Outer.Left, p, parent.Outer.Right, parent.Outer.Bottom);

            // 親の下側をp地点まで縮める
            parent.Outer.Bottom = child.Outer.Top;
        }
        else
        {
            // 横方向に分割する
            if (Check_Division_Size(parent.Outer.Width) == false)
            {
                // 横幅が足りない
                // 親区画を戻しておしまい
                division_list.Add(parent);
                return;
            }

            // 分割ポイントを求める
            int a = parent.Outer.Left + (Define_Value.MIN_ROOM + Define_Value.MERGIN_SIZE);
            int b = parent.Outer.Right - (Define_Value.MIN_ROOM + Define_Value.MERGIN_SIZE);

            // AB間の距離を求める
            int ab = b - a;

            // 最大の部屋サイズを超えないようにする
            ab = Mathf.Min(ab, Define_Value.MAX_ROOM);

            // 分割点を求める
            int p = a + Random.Range(0, ab + 1);

            // 子区画に情報を設定
            child.Outer.Set_Position(
                p, parent.Outer.Top, parent.Outer.Right, parent.Outer.Bottom);

            // 親の右側をp地点まで縮める
            parent.Outer.Right = child.Outer.Left;
        }

        // 次に分割する区画をランダムで決める
        if (Random.Range(0, 2) == 0)
        {
            // 子を分割する
            division_list.Add(parent);
            division_list.Add(child);
        }
        else
        {
            // 親を分割する
            division_list.Add(child);
            division_list.Add(parent);
        }
        // 分割処理を再帰呼び出し (分割方向は縦横交互にする)
        Split_Divison(!is_vertical);
    }
Ejemplo n.º 5
0
    /// <summary>
    /// 指定した部屋の間を通路でつなぐ
    /// </summary>
    /// <param name="divA">部屋1</param>
    /// <param name="divB">部屋2</param>
    /// <param name="bGrandChild">孫チェックするかどうか</param>
    /// <returns>つなぐことができたらtrue</returns>
    bool Create_Road(Dungeon_Division divA, Dungeon_Division divB, bool bGrandChild = false)
    {
        if (divA.Outer.Bottom == divB.Outer.Top || divA.Outer.Top == divB.Outer.Bottom)
        {
            // 上下でつながっている
            // 部屋から伸ばす通路の開始位置を決める
            int x1 = Random.Range(divA.Room.Left, divA.Room.Right);
            int x2 = Random.Range(divB.Room.Left, divB.Room.Right);
            int y  = 0;

            if (bGrandChild)
            {
                // すでに通路が存在していたらその情報を使用する
                if (divA.HasRoad())
                {
                    x1 = divA.Road.Left;
                }
                if (divB.HasRoad())
                {
                    x2 = divB.Road.Left;
                }
            }

            if (divA.Outer.Top > divB.Outer.Top)
            {
                // B - A (Bが上側)
                y = divA.Outer.Top;
                // 通路を作成
                divA.CreateRoad(x1, y + 1, x1 + 1, divA.Room.Top);
                divB.CreateRoad(x2, divB.Room.Bottom, x2 + 1, y);
            }
            else
            {
                // A - B (Aが上側)
                y = divB.Outer.Top;
                // 通路を作成
                divA.CreateRoad(x1, divA.Room.Bottom, x1 + 1, y);
                divB.CreateRoad(x2, y, x2 + 1, divB.Room.Top);
            }
            Fill_Dungeon_Rectangle(divA.Road);
            Fill_Dungeon_Rectangle(divB.Road);

            // 通路同士を接続する
            FillHLine(x1, x2, y);

            // 通路を作れた
            return(true);
        }

        if (divA.Outer.Left == divB.Outer.Right || divA.Outer.Right == divB.Outer.Left)
        {
            // 左右でつながっている
            // 部屋から伸ばす通路の開始位置を決める
            int y1 = Random.Range(divA.Room.Top, divA.Room.Bottom);
            int y2 = Random.Range(divB.Room.Top, divB.Room.Bottom);
            int x  = 0;

            if (bGrandChild)
            {
                // すでに通路が存在していたらその情報を使う
                if (divA.HasRoad())
                {
                    y1 = divA.Road.Top;
                }
                if (divB.HasRoad())
                {
                    y2 = divB.Road.Top;
                }
            }

            if (divA.Outer.Left > divB.Outer.Left)
            {
                // B - A (Bが左側)
                x = divA.Outer.Left;
                // 通路を作成
                divB.CreateRoad(divB.Room.Right, y2, x, y2 + 1);
                divA.CreateRoad(x + 1, y1, divA.Room.Left, y1 + 1);
            }
            else
            {
                // A - B (Aが左側)
                x = divB.Outer.Left;
                divA.CreateRoad(divA.Room.Right, y1, x, y1 + 1);
                divB.CreateRoad(x, y2, divB.Room.Left, y2 + 1);
            }
            Fill_Dungeon_Rectangle(divA.Road);
            Fill_Dungeon_Rectangle(divB.Road);

            // 通路同士を接続する
            FillVLine(y1, y2, x);

            // 通路を作れた
            return(true);
        }

        // つなげなかった
        return(false);
    }