[Unity] 5) Block


블록이 일치하면 상위 블록을 처리하여 간격을 채워야 합니다.

그래서 아래와 같이 3단계로 나누었습니다.

1. 공유 영역

2. 이동 거리 계산

3. 재배치

구역 분류


영역을 분할하고 다음과 같은 배열에 저장합니다.

    void DivideSection(ref List<List<int>> DivideBlocks)
    {
        // (BAISC) (EMPTY) (BAISC) (EMPTY) 순으로 값 저장
        for (int i = 0; i < WIDTH; i++)
        {
            int countBasic = 0;
            int countEmpty = 0;

            bool isBasic = true;
            DivideBlocks.Add(new List<int>());
            for (int j = HEIGHT - 1; j > -1; j--)
            {
                if (board._blocks(i + j * HEIGHT).GetComponent<BlockController>().info.blockType != BlockType.EMPTY)
                {
                    if (!isBasic)
                    {
                        isBasic = true;
                        DivideBlocks(i).Add(countEmpty);                        
                        countEmpty = 0;
                    }
                    countBasic++;
                }
                else if (board._blocks(i + j * HEIGHT).GetComponent<BlockController>().info.blockType == BlockType.EMPTY)
                {
                    if (isBasic)
                    {
                        isBasic = false;

                        if (j != HEIGHT - 1)
                            DivideBlocks(i).Add(countBasic);

                        countBasic = 0;
                    }
                    countEmpty++;
                }
            }

            if (isBasic)
                DivideBlocks(i).Add(countBasic);
            else
                DivideBlocks(i).Add(countEmpty);
        }
    }

이동 거리 계산

홀수(공백), 짝수(기본)

빈 값이 자신보다 낮은 만큼 블록이 내려가기 때문에

그래서 홀수라면 간격을 늘리고,

짝수의 경우 각 블록은 (HEIGHT-1) – (Distance + BasicCount)의 블록으로 거리 값을 이동해야 합니다.

    void CalDistance(ref int(,) moveDistance, List<List<int>> DivideBlocks)
    {
        for (int i = 0; i < DivideBlocks.Count; i++)
        {
            if (DivideBlocks(i).Count == 1) continue;

            int distance = 0;
            int basicCount = DivideBlocks(i)(0);
            for (int j = 1; j < DivideBlocks(i).Count; j++)
            {
                if (j % 2 == 1) distance += DivideBlocks(i)(j);

                else
                {
                    for (int r = 0; r < DivideBlocks(i)(j); r++)
                    {
                        if (board._cells(i, (HEIGHT - 1 - (distance + basicCount))).GetComponent<CellController>().info.cellType == CellType.BASIC)
                            moveDistance(i, (HEIGHT -1 - (distance + basicCount))) = distance;
                        basicCount++;
                    }
                }
            }
        }
        
    }

이동하다

이동 거리 값이 0보다 크면 블록을 아래로 이동

    void BlockMoveDown(int(,) moveDistance)
    {
       bool flag = false;
       for (int i = WIDTH - 1; i > -1; i--)
        {
            for (int j = HEIGHT - 1; j > -1; j--)
            {
                if (moveDistance(i, j) > 0)
                {
                    isCoroutineAcitve = true;
                    flag = true;
                    //Debug.Log("BlockDown");
                    ChangeBlockValue(board._blocks(i + j * HEIGHT).GetComponent<BlockController>(), board._blocks(i + (j + moveDistance(i, j)) * HEIGHT).GetComponent<BlockController>(), true, 3);
                }
            }
        }

        if (flag)
        {
            isCoroutineAcitve = false;
        }