Unity/3Match

[Unity] 5) Block Down

GiveZero 2023. 2. 20. 17:01

블럭이 매칭되면 빈칸을 채우기 위해 위에 있는 블럭을 처리해야 할것이다.

 

따라서 다음과 같이 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);
        }
    }

이동거리 계산하기

홀수번째(Empty), 짝수번째(Basic)

자신보다 아래있는 Empty 값 만큼 블럭이 내려가기 때문에

때문에 홀수번 째 일때 distance를 증가시키고,

짝수번째 일때 블럭 한개마다 (HEIGHT-1) - (distance + basicCount) 에 있는 블럭에 distance값 만큼 이동 예약

    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++;
                    }
                }
            }
        }
        
    }

이동하기

movedistance 값이 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;
        }