1인 개발/숫자의 신

숫자의 신 개인 프로젝트 3일차

잼잼재미 2024. 7. 25. 00:55

구현 내용


1. Block 생성


 

  • 일정 시간마다 Block 프리팹을 반복해서 생성
  • Block은 수평, 수직 방향으로 이동
  • Block이 벽에 닿으면 수평 이동 방향 변경
  • Destroyline에 닿으면 Block 파괴

 

2. Blcok 파괴


 

  • 생성된 Block들 중, 계산 결과가 있다면 Block 파괴 후, Score 획득
  • Block을 끝까지 계산 못하면 HP 감소

 

 

GameController 스크립트

public Dictionary<float, GameObject> Blocks;

IEnumerator COCreateBlock()
{
    while (true)
    {
        SetBlockNumber(10);

        yield return new WaitForSeconds(BlockCreateTime);
    }
}

private void CreateBlock(int range) // 0 ~ range 중 랜덤 생성
{
    while (true)
    {
        int num = Random.Range(0, range + 1);
        if (Blocks.ContainsKey(num)) continue;
        else
        {
            float value = Random.Range(-2f, 2f);
            GameObject obj = Instantiate(BlockPrefab, new Vector3(value, 5.2f, 0), Quaternion.identity);
            obj.GetComponent<Block>().SetBlockNumber(num);
            Blocks.Add(num, obj);
            break;
        }
    }
}

 

Dictionary를 이용해서 랜덤으로 생성된 Block의 숫자를 Dictionary의 key 값으로, 그 숫자의 Block GameObject를 value 값으로 추가했다.

 

 

CalculationFormula 스크립트

public void CalculateNumber()
{
    if (_fillNumberFrames != _numberFramesCount) return;

    string cal = "";
    int frameCount = 0;
    int calCount = 0;

    for (int i = 0; i < _numberFramesCount + _calculationsCount; i++)
    {
        if(i % 2 == 0)
        {
            cal += _numberFrames.transform.GetChild(frameCount).GetChild(0).GetComponent<TextMeshProUGUI>().text;
            frameCount++;
        }
        else
        {
            cal += _calculations.transform.GetChild(calCount).GetChild(0).GetComponent<TextMeshProUGUI>().text;
            calCount++;
        }
    }

    string newCal = cal.Replace("×", "*");
    string newCal2 = newCal.Replace("÷", "/");
    float result = Evaluate(newCal2);

    if(_gameController.Blocks.ContainsKey(result))
    {
        GameObject obj = _gameController.Blocks[result];
        Destroy(obj);
        _gameController.GetScore(_numberFramesCount * 100);
        _gameController.Blocks.Remove(result);
        _gameController.SetactiveCalculationFormula();
    }
    else ClearNumber();
}

 

계산 결과가 Dictionary의 key 값에 있다면, 해당 key 값의 value 값인 Block GameObject를 파괴하고, Dictionary에서 삭제했다. 그리고 Score를 획득하도록 구현했다.

 

 

트러블 슈팅


1. Dictionary 사용


계산결과 값이 생성된 BlockNumber 중 존재하는지 확인을 위한 방법이 필요했다. 

 

 

public List<float> BlockNumbers;

 

처음에는 Block이 생성 될 때마다 float 형식의 List에 생성된 Block의 Number을 추가했다. 계산결과를 List가 가지고 있는지는 Contains 함수를 통해 쉽게 확인 가능하지만, 해당하는 값의 Block을 파괴하기 위해서는 추가적인 방법이 필요했다.

 

 

public List<float> BlockNumbers;
public List<GameObject> Blocks;

public void BlockDestroy(int num)
{
    for (int i = 0; i < Block.Count; i++)
    {
        if (Block[i].GetComponent<Block>().Number == num) Destroy(Block[i]);
    }
}

 

Block들을 관리하는 추가 List를 생성하고 계산결과의 값과 동일한지 모든 Block들을 순회하여 같다면 파괴하도록 구현할 수 있다. 하지만 이 방법은 두개의 List를 만들어야하고, Block들 모두 순회해야기 때문에 O(n)의 시간복잡도 가져서 비효율적이라고 생각했다. 

 

 

GameController 스크립트

public Dictionary<float, GameObject> Blocks;

private void CreateBlock(int range)
{
    while (true)
    {
        int num = Random.Range(0, range + 1);
        if (Blocks.ContainsKey(num)) continue;
        else
        {
            GameObject obj = Instantiate(BlockPrefab, new Vector3(0, 5.2f, 0), Quaternion.identity);
            obj.GetComponent<Block>().SetBlockNumber(num);
            Blocks.Add(num, obj);
            break;
        }
    }
}

 

 

CalculationFormula 스크립트

public void CalculateNumber()
{
    if(_gameController.Blocks.ContainsKey(result))
    {
        GameObject obj = _gameController.Blocks[result];
        Destroy(obj);
    }
}

 

두개의 List를 사용하는 대신 Dictionary를 사용할 수 있었다. Dictionary는 key 값과 value 값을 쌍으로 저장하고 검색하는데 최적화 된 자료구조다. 효율적으로 검색이 가능하기 때문에 O(1)의 상수 시간복잡도를 가져서 훨씬 효율적이라고 생각했다. 랜덤으로 생성한 Number를 key 값으로 설정하고 해당 값을 가지는 Block을 value 값으로 설정했다. 

 

 

회고


간단한 프로토 타입을 완성했다. Block의 움직임 같은 경우는 update문에서 position을 더하는 것으로 쉽게 구현했고, 계산 결과를 Dictionary의 key 값을 조회해서 있다면 해당 value GameObject를 파괴하도록 구현했다. 생각보다 어려웠던 부분은 거의 없었다. 이제 Item Block을 만들어 보도록 하겠다!