TIL

2023/11/10 TIL

미역제자 2023. 11. 10. 21:18


오늘은 개인과제 마무리에 힘을썻다.

아이템 장착시 증가하는 스탯, 레벨별 스탯, 던전 구현 등에 집중했다.

 

먼저 콘솔을 꾸며주었다.

Console.BackgroundColor = ConsoleColor.DarkGreen; //초록색 배경
Console.ForegroundColor = ConsoleColor.White; //흰 글씨
Console.SetWindowSize(82, 21); //타이틀에 맞춰 화면 크기 변경

 

BackgroundColor는 뒤의 배경을 바꿔주고

ForegroundColor는 글씨의 색을 바꿔준다.

나는 타이틀의 크기에 맞게, SetWindowSize를 이용해 콘솔창의 크기도 바꿔주었다.

 

공격력 50, 방어력 10의 장비를 착용하니 스탯이 올라가는 모습이다.

코드는 다음과 같다.

public void EquipItem(int input)
{
    //착용하려는 장비가 인벤토리 안에 있는 장비인가
    if (input > 0 && input <= Inventory.Count)
    {
        //배열은 0부터 시작하기 때문에 input-1
        var item = Inventory[input - 1];
        if (!item.IsEquipped) //착용여부가 false일때
        {
            item.IsEquipped = true;//착용여부를 true로 바꿈
            Console.WriteLine($" [{item.ItemName}]을(를) 장착했습니다.");
            //착용된 아이템의 스탯을 캐릭터 스탯에 적용
            Atk += item.ItemAtk;
            Def += item.ItemDef;
        }
        else
        {
            item.IsEquipped = false;//착용여부를 false로 바꿈
            Console.WriteLine($" [{item.ItemName}]을(를) 해제했습니다.");
            //착용 해제된 아이템의 스탯을 캐릭터 스탯에 적용
            Atk -= item.ItemAtk;
            Def -= item.ItemDef;
        }
    }
    else
    {
        Console.WriteLine(" 잘못된 인덱스입니다.");
    }
}

 

Character 클래스에 넣은 메소드이다.

아이템을 장착, 해제하는 메소드에 

player.EquipItem(input); 을 넣고,

장착할때 스탯을 더하고, 해제할때 스탯을 빼는 방식으로 구현했다.

 

원래는 

private void UpdateStats()
{
    foreach (var item in Inventory)
    {
        if (item.IsEquipped)
        {
            Atk += item.ItemAtk;
            Def += item.ItemDef;
            Hp += item.ItemHp;
        }
        else
        {
            Atk -= item.ItemAtk;
            Def -= item.ItemDef;
            Hp -= item.ItemHp;
        }
    }
}

 

상태창 업데이트 방식으로 아이템을 장착할 때 이 메소드를 활성화 시키는 방식으로 진행하려고 했다.

하지만 이 방식으로는 인벤토리에 아이템이 2개 이상 있을 경우, 아이템을 하나만 장착하게되면 장착한 아이템의 스탯만 오르고 장착하지 않은 아이템의 스탯은 오히려 감소되는 오류가 발생했다. 그래서 해결방식을 고민하다가 아이템이 장착될 때 같이 스탯이 오르고, 해제할 때 같이 스탯이 내려가는 방식으로 구현했다.

 

다음으로는 레벨업을 구현했다.

먼저 레벨업에 필요한 경험치량을 구현했다.

(뭔가 이상한 부분이 많긴 하다)

//레벨 범위 Class
public class LevelRange
{
    public int startLevel;
    public int endLevel;
    public int experienceCapIncrease;
}

 

startlevel~endlevel까지의 경험지양을 정의하는 클래스를 만들었다.

 public int level = player1.Level;
 public static int experienceCap;


 public static List<LevelRange> levelRanges = new List<LevelRange>();

 //필요레벨업 수치
 void LevelStart()
 {
     levelRanges = new List<LevelRange>
     {
     new LevelRange { startLevel = 1, endLevel = 5, experienceCapIncrease = 10 },
     new LevelRange { startLevel = 5, endLevel = 10, experienceCapIncrease = 50 },
     new LevelRange { startLevel = 10, endLevel = 50, experienceCapIncrease = 100 },
     new LevelRange { startLevel = 50, endLevel = 100, experienceCapIncrease = 500 }
     };
     // 리스트 0번째의 경험치량 불러오기
     experienceCap = levelRanges[0].experienceCapIncrease;
 }

 //경험치 추가
 public static void IncreaseExperience(Character player1, int amount)
 {
     // 들어오는 경험치 더하기
     player1.Experience += amount;

     // 레벨업 하는지 확인
     LevelUpChecker(player1);
 }

 //경험치가 필요경험치 수치를 전부 채우면 레벨업
 public static void LevelUpChecker(Character player1)
 {
     // 만약 경험치가 꽉찬다면?
     if (player1.Experience >= experienceCap)
     {
         // 레벨 업
         player1.Level++;
         // 경험치 줄여주기
         player1.Experience -= experienceCap;

         int experienceCapIncrease = 0;
         foreach (LevelRange range in levelRanges)
         {

             // 만약 현재 레벨이 리스트안에 있는 startLevel보다 크고 endLevel보다 적으면 실행하고 빠져나오기
             // 간단하게 0범 리스트에 조건이 맞으면 나오고 초기화

             if (player1.Level >= range.startLevel && player1.Level <= range.endLevel)
             {
                 experienceCapIncrease = range.experienceCapIncrease;
                 break;
             }
         }

         experienceCap += experienceCapIncrease;
     }
 }

 

그 다음에 만렙을 100으로 잡고, 그 사이 구간의 필요 레벨업 경험치량을 List로 만들어 준다.

IncreaseExperience메소드를 만들어서 획득한 경험치를 player1의 경험치에 저장한다.

그 후, 그 경험치량이 레벨업을 하기에 충분한 경험치인지 판단을 하는 LevelUpChecker 메소드를 실행한다.

LevelUpChecker 메소드에서는 경험치가 필요 경험치량을 넘어갔다면 레벨업을 해주고

남은 경험치를 다시 플레이어의 경험치에 저장한다.

코드를 이리저리 주어와서 붙인거기 때문에 깔끔하게 나오지 않는 모습이다.

 

그리고 레벨에 따른 스탯 증가량은 Character Class에 만들었다.

private int _level; // private 필드로 변경
public int Level
{
    get { return _level; }
    set
    {
        // Level이 변경될 때마다 레벨업 로직 수행
        for (int i = _level + 1; i <= value; i++)
        {
            Atk += (i - 1); // 레벨업 할 때마다 Atk가 (Level-1)만큼 증가
            Def += (i - 1); // 레벨업 할 때마다 Def가 (Level-1)만큼 증가
        }
        _level = value;
    }
}

 

마지막으로 던전을 구현한 것이다.

이지모드를 복사해서 붙여넣었다.

static void DunGeonEasy()
{
    Console.Clear();
    Console.WriteLine();
    Console.ForegroundColor = ConsoleColor.Green;
    Console.WriteLine(" 이지모드 던전에 입장하시겠습니까?.");
    Console.ForegroundColor = ConsoleColor.White;
    Console.Write(" 권장 스텟은 "); 
    Console.ForegroundColor = ConsoleColor.Magenta;
    Console.Write("공격력 10 이상");
    Console.ForegroundColor = ConsoleColor.Blue;
    Console.Write(" 방어력 10 이상");
    Console.ForegroundColor = ConsoleColor.White;
    Console.WriteLine("입니다.");
    Console.WriteLine(" 이지모드 던전에서는 슬라임이 등장합니다.");
    Console.WriteLine();
    Console.WriteLine(" 입장하시겠습니까?");
    Console.WriteLine();
    Console.WriteLine(" 1. 예");
    Console.WriteLine();
    Console.WriteLine(" 2. 아니요");
    Console.WriteLine();

    int input = CheckValidInput(1, 2);
    switch (input)
    {
        case 1:
            //이지모드 던전 입장
            EasyInDunGeon(player1);
            break;
        case 2:
            //뒤로
            DungeonPotal();
            break;
    }
}
//이지 모드 던전 입장 후
static void EasyInDunGeon(Character player1)
{
    Console.Clear();
    Console.WriteLine();
    Console.WriteLine(" 진행하려면 enter");
    Console.WriteLine();
    Console.ReadKey();
    Console.ForegroundColor = ConsoleColor.Green;
    Console.WriteLine(" 슬라임 등장!");
    Console.ForegroundColor = ConsoleColor.White;
    Console.ReadKey();

    Console.WriteLine(" 전투 시작");
    Console.WriteLine();
    Console.ReadKey();
    Console.WriteLine(" 슬라임의 공격!");
    Damage = 30 - player1.Def;
    if (Damage <= 0)
    {
        Damage = 0;
    }
    player1.Hp = player1.Hp - Damage;
    Console.WriteLine($" 체력이 {Damage} 감소했다.");
    Console.ReadKey();

    if (player1.Hp > 0)
    {
        Console.WriteLine($"당신의 남은 체력 : {player1.Hp}");
        Console.WriteLine();
        Console.WriteLine(" 당신의 공격!");
        Console.WriteLine();
        Console.WriteLine(" 슬라임을 처치했습니다.");
        Console.WriteLine();
        Console.ReadKey();
        Console.WriteLine(" 100G 획득");

        IncreaseExperience(player1, 20);
        Console.WriteLine(" 20EXP 획득");
        Console.ReadKey();

        player1.Gold = player1.Gold + 100;
        Console.WriteLine();
        Console.WriteLine(" 던전을 클리어 하셨습니다.");
        Console.WriteLine(); 
        Console.WriteLine(" 1. 이지모드 다시 하기");
        Console.WriteLine(" 2. 난이도 변경");
        Console.WriteLine(" 3. 마을로 귀환하기");
        Console.WriteLine(">>");


        int input = CheckValidInput(1, 3);
        switch (input)
        {
            case 1:
                //이지 던전 다시 돌기
                EasyInDunGeon(player1);
                break;
            case 2:
                //던전포탈로 귀환
                DungeonPotal();
                break;
            case 3:
                //마을로 귀환
                ShowVillageFirst();
                break;
        }
    }
    else
    {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine(" You Died");
        Console.WriteLine(" Game Over");
        Console.ForegroundColor = ConsoleColor.White;         
    }

}

 

굉장히 긴 것을 볼 수 있다.

Moster Class를 통해 간략화를 하려고 했지만

오늘은 시간관계상 포기! 내일 마저할까 한다.


 

오늘로써 대부분의 기능을 구현 완료했고, 실제로 실행도 잘 되는걸 보니 뿌듯했다.

 

오늘은 다른분들이 풀었던 3주차 연습문제 설명을 들었다.

다들 LINQ를 쓰고, 못보던 코드들을 쓰고...

아직 공부할게 많다는 생각이 들었다.

 

'TIL' 카테고리의 다른 글

2023/11/13 TIL  (1) 2023.11.13
2023/11/11 TIL  (1) 2023.11.11
2023/11/09 TIL  (2) 2023.11.09
2023/11/08 TIL  (0) 2023.11.08
2023/11/07 TIL  (0) 2023.11.07