내일배움캠프 74일차 TIL : 스테이지 한 페이즈당 여러 종류 몬스터 나오게 하기

woollim·어제
0

내일배움캠프TIL

목록 보기
67/68
post-thumbnail

■ 개요

○ 오늘 계획

  • 스테이지 한 페이즈당 여러 종류 몬스터 나오게 하기
  • 버그 고치기


■ 프로젝트

  • 한페이즈당 여러몬스터가 섞여 나오면 좋겠다는 의견이 있어서 바꾸기로 했다!
  • ㅠㅠ 스테이지 N차 수정중

○ StageManager

    /// <summary>
    /// 스테이지 ID 에 맞는 몬스터를 소환해주는 함수 입니다
    /// </summary>
    public void EnterStageMonsterSpawn()
    {
        switch (StageType)
        {
            case StageType.Boss:
                BossStageData bossStage = Managers.Data.GameDataBase.BossStageDatas[Managers.Stage.StageID];
                Managers.Character.SpawnMonster(bossStage);
                break;
            case StageType.Normal:
                NormalStageData normalStage = Managers.Data.GameDataBase.NormalStageDatas[Managers.Stage.StageID];
                Managers.Character.SpawnMonster(normalStage);
                break;
        }
    }

○ CharacterManager

/// <summary>
/// 보스 몬스터를 생성해주는 함수 입니다.
/// </summary>
public void SpawnMonster(BossStageData bossStage)
{
    int spawnPhase = Managers.Game.CurrentMonsterPhase; // 현재 페이즈

    Logger.Log($"현재 페이즈 : {spawnPhase}, 맥스 페이즈 : {bossStage._phaseCount}");

    if (spawnPhase < bossStage._phaseCount) // 현재 페이즈가 최대 페이즈보다 작은지 확인
    {
        for (int i = 0; i < bossStage._monsterIDs.Count; i++) // 현재 페이즈의 몬스터 id 종류 만큼 포문
        {
            // id당 몬스터 수만큼 반복해서 초기화
            InitMonsterPool(bossStage._monsterIDs[i], bossStage._monsterQuantity[i], spawnPhase);
        }
    }
}

/// <summary>
/// 노말 몬스터를 생성해주는 함수 입니다.
/// </summary>
public void SpawnMonster(NormalStageData normalStage)
{
    int spawnPhase = Managers.Game.CurrentMonsterPhase; // 현재 페이즈

    Logger.Log($"현재 페이즈 : {spawnPhase}, 맥스 페이즈 : {normalStage._phaseCount}");

    if (spawnPhase < normalStage._phaseCount) // 현재 페이즈가 최대 페이즈보다 작은지 확인
    {
        for(int i = 0; i < normalStage._monsterIDs.Count; i++) // 현재 페이즈의 몬스터 id 종류 만큼 포문
        {
            // id당 몬스터 수만큼 반복해서 초기화
            InitMonsterPool(normalStage._monsterIDs[i], normalStage._monsterQuantity[i], spawnPhase);
        }
    }
}

/// <summary>
/// 몬스터 종류별 에너미 풀을 초기화 하는 함수 입니다.
/// </summary>
/// <param name="monsterID">몬스터 ID</param>
/// <param name="quantity">몬스터 수</param>
private void InitMonsterPool(int monsterID, int quantity, int spawnPhase)
{
    var monsterPrefab = Managers.Resource.LoadAsset<Enemy>(Managers.Data.GameDataBase.MonsterDatas[monsterID]._prefabPath);
    if (monsterPrefab == null) return;

    if (!enemyPool.ContainsKey(monsterID))
    {
        enemyPool.Add(monsterID, Managers.Pool.GetPool<Enemy>(monsterPrefab, quantity));
    }

    Managers.Game.AddEnemyCount(spawnPhase, quantity);

    for (int j = 0; j < quantity; j++)
    {
        var enemy = enemyPool[monsterID].Get(); // 에너미 풀에서 에너미 가져옴
        enemy.SetMonster(monsterID, spawnPhase);
    }
}

○ GameManager

/// <summary>
/// 에너미 카운트 딕셔너리에 에너미 종류와 수를 추가하는 함수입니다.
/// </summary>
/// <param name="monsterID">몬스터 ID, 딕셔너리 키</param>
/// <param name="quantity">몬스터 수, 딕셔너리 밸류</param>
public void AddEnemyCount(int spawnPhase, int quantity)
{
    if (stageEnemyCount.ContainsKey(spawnPhase))
    {
        stageEnemyCount[spawnPhase] += quantity;
    }
    else
    {
        stageEnemyCount.Add(spawnPhase, quantity);
    }
}

/// <summary>
/// 에너미를 처치할때마다 호출되는 함수입니다. 에너미가 처치되면 하는 후속작업을 합니다.
/// </summary>
/// <param name="monsterID">몬스터 ID</param>
public void SubEnemyCount(int spawnPhase, Enemy enemy)
{
    // 딕셔너리에서 phase를 키로 해당되는 밸류(몬스터 수)를 찾습니다.
    if (!stageEnemyCount.TryGetValue(spawnPhase, out int monsterCount))
        return;

    TopReputeScore += enemy.Stat.ReputeNumber;
    stageEnemyCount[spawnPhase]--;

    if (Managers.Stage.StageType == StageType.Normal && LastSpawnMonsterPhase != spawnPhase)
    {
        int lastPhase = Managers.Data.GameDataBase.NormalStageDatas[Managers.Stage.StageID]._phaseCount - 1;
        int phaseMonsterCount = 0;
        for(int i = 0; i < Managers.Data.GameDataBase.NormalStageDatas[Managers.Stage.StageID]._monsterQuantity.Count; i++)
        {
            phaseMonsterCount += Managers.Data.GameDataBase.NormalStageDatas[Managers.Stage.StageID]._monsterQuantity[i];
        }

        Logger.Log($"stageEnemyCount[spawnPhase] < phaseMonsterCount : {stageEnemyCount[spawnPhase] < phaseMonsterCount}");

        // 마지막 페이즈가 아니고, 페이즈 별 몬스터 절반이 죽었을 경우에
        if (CurrentMonsterPhase < lastPhase && stageEnemyCount[spawnPhase] < phaseMonsterCount / 2)
        {
            CurrentMonsterPhase++; // 현재 페이즈 증가
            LastSpawnMonsterPhase = spawnPhase;
            // 다음 페이즈 몬스터 소환
            Managers.Character.SpawnMonster(Managers.Data.GameDataBase.NormalStageDatas[Managers.Stage.StageID]);
            Logger.Log($"{CurrentMonsterPhase}페이즈 시작");
        }
    }

    if (stageEnemyCount[spawnPhase] <= 0) // 다 죽였다면
    {
        stageEnemyCount.Remove(spawnPhase);
        if (stageEnemyCount.Count == 0) // 모든 종류의 몬스터가 죽었다면
        {
            StageClear(enemy.gameObject.transform.position);
        }
    }
}

/// <summary>
/// 에너미 카운트 딕셔너리를 리셋합니다.
/// </summary>
public void ResetEnemyCount()
{
    stageEnemyCount.Clear();
    CurrentMonsterPhase = 0;
    LastSpawnMonsterPhase = -1;

    ResetCurrentReward();
}

0개의 댓글