연속적인 타일이 3개 이상인지 확인하기

타일을 생성시에 연속적으로 3개가 존재하는지 확인

- 상하좌우 3개 이상인지 검사하므로 4칸은 검사하지 않아도 됨

- while문을 돌면서 3개 이상이라면 Explode 메서드를 통해 타일을 파괴

private void ReArrangeBoard()
{
    bool isExploded = true;

    while (isExploded)
    {
        isExploded = false;

        Vector2Int boardIndex;
        for (int i = 0; i < boardSize; i++)
        {
            for (int j = 0; j < boardSize; j++)
            {
                if (i >= EXPLOSION_COUNT -1 || j >= EXPLOSION_COUNT -1)
                {
                    boardIndex = new Vector2Int(i, j);
                    if (CheckExplosion(boardIndex))
                        isExploded = true;
                }
            }
        }

        if (isExploded)
            Explode();
    }
}

 

 

자연스러운 타일 이동 연출하기

타일이 파괴 된 후 자연스러운 이동 구현

1. 먼저 기존에 있던 타일 위치들 옮기는 것을 구현 (ArrangeBoard 메서드)

- 2차원 배열 Board를 기준으로 윗 타일이 null인지 확인하고 아래로 한 칸씩 위치를 저장

- 인덱스에 해당하는 목표 위치가 필요하므로 Vector2Int를 Key로 Vector2를 Value 값으로 하는 Dictionary에 저장 (_targetDict)

2. 추가적으로 생성해야 하는 타일들을 시작 위치로 생성 뒤 목표 위치 저장

3. _targetDict를 순회하며 코루틴으로 이동

- _nullCountArr라는 배열으로 해당 컬럼에 타일이 몇 개 생성 되었는지 카운트하고 다음 생성되는 타일의 위치 정보를 갱신

private void ArrangeBoard(bool isSequencial)
{
    Vector2Int tempIndex = Vector2Int.zero;


    for (int i = 0; i < boardSize; i++)
    {
        for (int j = 0; j < boardSize; j++)
        {
            tempIndex.x = j;
            tempIndex.y = i;
            if (!_board[tempIndex])
            {
                _nullQueue.Enqueue(tempIndex);
            }
            else if (_nullQueue.Count > 0)
            {
                Vector2Int nullIndex = _nullQueue.Dequeue();
                _board[nullIndex] = _board[tempIndex];
                _board[nullIndex].SetIndex(nullIndex);

                _board[tempIndex] = null;
                _nullQueue.Enqueue(tempIndex);

                Vector2 targetPos = _boardPosArr[nullIndex.x, nullIndex.y];

                if (isSequencial)
                {
                    if (!_targetPosDict.ContainsKey(nullIndex))
                        _targetPosDict.Add(nullIndex, targetPos);
                    else
                        _targetPosDict[nullIndex] = targetPos;
                }
                else
                {
                    _board[nullIndex].Transform.position = targetPos;
                }
            }
        }


        while (_nullQueue.Count > 0)
        {
            CreateAdditionalTile(isSequencial);
        }

        Array.Fill(_nullCountArr, 0);
        _nullQueue.Clear();
    }

    if (isSequencial)
    {
        foreach (var item in _targetPosDict)
        {
            StartCoroutine(_board[item.Key].Move(item.Value, arrangeTime));
        }
    
        _targetPosDict.Clear();
    }
}

private void CreateAdditionalTile(bool isSequencial)
{
    /* 타일 생성 및 초기화 로직 
    	...
    */
    
    int columnNullCount = _nullCountArr[nullIndex.y]++;
    Vector2 startPos = tile.Transform.position;
    startPos += new Vector2(_halfUnit + _unit * nullIndex.y, _halfUnit + _unit * (boardSize + columnNullCount));

    Vector2 targetPos = _boardPosArr[nullIndex.x, nullIndex.y];

    if (isSequencial)
    {
        _board[nullIndex].Transform.position = startPos;
        _targetPosDict.Add(nullIndex, targetPos);
    }
    else
    {
        _board[nullIndex].Transform.position = targetPos;
    }
}

결과

- 떨어지는 위치가 다른 버그 존재 (코루틴 또는 코루틴 중 터치 문제로 보임)

- 터지고 나서 추가 타일에 대한 체크도 필요

+ Recent posts