2025.02.04 (화)

윤혜진·2025년 2월 4일
1

TIL

목록 보기
18/42

📍오늘의 학습 키워드

  • 텍스트 RPG 만들기 (2)
    • 이름 입력받는 기능 추가
    • 직업 구현
      • 직업 입력받기
      • 직업별 스텟 정하기
      • 직업별 장비 차별화
    • 던전 입장 기능 추가
    • 레벨업 기능 추가

📍학습 내용

  • 이름 입력받는 기능 추가

    • 그냥 평범하게 입력을 받아도 좋았겠지만 괜히 변주를 주고 싶어서 이름을 입력받는 기능에 선택지를 넣어봤다.
    • 1을 누르면 용사님 고정, 2를 누르면 임의의 이름이 랜덤으로 나오고, 3을 누르면 이름을 직접 입력할 수 있다.
    • 임의의 이름을 랜덤으로 뽑아주는 메서드는 Player에서 구현해주었다 :
      //임의의 이름 10개를 배열에 넣어준다.
      tempName = new string[10]{ "올든", "세드릭", "다리안", "에즈란", "카엘",
                                 "오린", "리븐", "테론", "베이론", "제피르"};
      
      //랜덤으로 0~배열길이 까지의 랜덤한 숫자를 뽑은 뒤
      //그 숫자에 해당하는 배열의 이름을 플레이어 이름으로 정해준다.
      public void RandomName()
      {
          Random rand = new Random();
          int index = rand.Next(0, tempName.Length);
      
          Name = tempName[index];
      }
  • 직업 구현

    • 직업은 전사, 마법사, 궁수 3개의 직업으로 나누었으며, Player 클래스에 enum으로 타입을 나눠주었다.

      public enum JobType
      {
          Warrior,
          Magician,
          Archer
      }
    • 플레이어가 직업을 선택하면 job 프로퍼티를 통해 플레이어의 초기스탯 또한 정해진다.

      
      // Job 프로퍼티
      public JobType Job
      {
          get { return job; }
          set
          {
              //JobType이 설정될 때 스탯들도 함께 설정되도록 한다.
              job = value;
              SetStats();
          }
      }
      
      // Job이 정해지면 아래 메서드가 실행된다.
      // 직업의 특성에 따라 스탯을 조금씩 다르게 만들어 줌.
      private void SetStats()
      {
          switch (job)
          {
              case JobType.Warrior:
                  Power = 10f;
                  Defense = 5f;
                  MaxHP = 100f;
                  Hp = MaxHP;
                  break;
      
              case JobType.Magician:
                  Power = 15f;
                  Defense = 3f;
                  MaxHP = 80f;
                  Hp = MaxHP;
                  break;
      
              case JobType.Archer:
                  Power = 12f;
                  Defense = 4f;
                  MaxHP = 90f;
                  Hp = MaxHP;
                  break;
          }
      }
    • 상점에서 파는 아이템들도 직업별로 조금씩 다르게 만들어주었다.

      //전사 방어구
      Items[0].Name = "수련용 갑옷";
      Items[0].Power = 0f;
      Items[0].Defense = 5f;
      Items[0].ItemInfo = "수련에 도움을 주는 갑옷입니다.";
      Items[0].Gold = 1000;
      Items[0].Type = ItemType.Armor;
      
      //마법사 방어구
      Items[0].Name = "수련용 로브";
      Items[0].Power = 0f;
      Items[0].Defense = 5f;
      Items[0].ItemInfo = "수련에 도움을 주는 로브입니다.";
      Items[0].Gold = 1000;
      Items[0].Type = ItemType.Armor;
      
      //궁수 방어구
      Items[0].Name = "수련용 튜닉";
      Items[0].Power = 0f;
      Items[0].Defense = 5f;
      Items[0].ItemInfo = "가볍지만 질기고, 빨래가 쉬운 수련용 튜닉입니다.";
      Items[0].Gold = 1000;
      Items[0].Type = ItemType.Armor;
  • 던전 입장 기능

    • 던전을 구현하기 위해 Dunjeon 클래스를 따로 만들었다!
    • Dunjeon 클래스 안에 속해있는 필드는 다음과 같다:
      • 던전 최소 방어력 (float def)
      • 보상 골드(int Gold)
      • 던전의 난이도(DunjeonType level)
    • DunjeonType은 던전의 난이도를 받으려고 만든 Enum타입 :
      public enum DunjeonType
      {
          Easy = 1,
          Nomal = 2,
          Hard = 3
      }
      
      //MainGame에서 이런식으로 입력받고 있음
      dunjeon.Level = (DunjeonType)input;
    • Dunjeon 클래스 안에 속해있는 메서드는 다음과 같다 :
      • ClearCheck: 던전 공략을 성공/실패하는지 체크하는 메서드
      • DungeonClear: 던전 공략 성공시 메세지를 출력하는 메서드
      • DungeonFail: 던전 공략 실패시 메세지를 출력하는 메서드
    • 이밖에 Player 클래스에도 받을 데미지와 보상을 계산하고 적용하는 Victory 메서드와, 현재 체력의 1/2만큼을 감소시켜주는 Defeat 메서드를 추가해주었다.
  • 레벨업 기능 추가

    • 던전 클리어시 플레이어의 Exp가 증가하도록 만들었다.
    • Exp 프로퍼티를 통해 exp에 값이 들어올 때마다 MaxExp와 비교하도록 만듦.
    • 만약 Exp가 MaxExp보다 값이 커지게 된다면, LevelUp 메서드가 실행된다.
    • Exp 프로퍼티를 사용한 코드:
      private int exp;
      public int Exp
      {
          get { return exp; }
          set
          {
              exp = value;
              if (exp >= MaxExp)
              {
                  LevelUp();
                  MaxExp++;
              }
          }
      }
    • LevelUp 메서드가 하는 일은 다음과 같다:
      • 플레이어의 level을 1 증가시키고, 지금까지 얻은 경험치를 0으로 초기화한다.
      • 레벨업에 필요한 경험치량(MaxExp)을 증가시킨다.
      • 플레이어의 최대 체력과 스탯을 일정량 증가시킨다.
      • 체력을 모두 회복한다.

📍겪은 어려움

  • 판매 후 장착 과정에서 예기치 못한 버그 발생

    • 구매 후 아이템을 장착/해제하는 과정은 문제가 없었으나, 구매 > 판매 > 아이템 장착을 하면 갑자기 판매되었던 아이템들이 인벤토리 목록으로 다시 튀어나오는 버그 발생.

    • 버그로 생긴 아이템들은 팔리지 않았지만 장착은 가능했고, 플레이어 스탯 또한 정말 장착된 것처럼 증가되어 있었음.

    • 원인: 어제 오류 해결을 위해 아이템에 새로 부여해 주었던 필드 InventoryNum을 제대로 초기화해주지 않아 발생한 문제였다.

      • 나는 어제 인벤토리 목록의 번호아이템 배열의 번호가 일치하지 않아 제대로 아이템 선택이 안 되는 버그가 발생했었다.
      • 그 버그를 해결하기 위해 내가 선택한 방법은 Item에 InventoryNum 이라는 새로운 int형 필드를 부여하고, 소유 중인 아이템들에게만 순서대로 InventoryNum 을 설정해 주었음.
      • 해당 코드 사진:
      • 보다시피 이 InventoryNumInit이라는 메서드는 for문을 통해 item 배열 크기만큼 반복하고, HaveNot 상태가 아닌 아이템들만 찾아서 인벤토리용 전용 번호(InventoryNum)를 부여해주고 있다. (이 메서드는 소유 아이템 변동이 일어날 때, 즉 구매 혹은 판매를 할 때마다 실행되도록 만들었다.)
      • 그런데 판매 메서드에서 내가 판매할 item[i]의 상태를 HaveNot 으로 바꾼 뒤, item[i]의 InventoryNum값은 따로 초기화를 해주지 않아 이러한 버그가 발생했던 것.
      • 해당 코드 사진:
      • 해결: 판매 후 아이템의 상태를 HaveNot으로 바꿔주며 InventoryNum 또한 -1로 초기화해주었더니 잘 돌아갔다.
  • 던전 구현 중 플레이어의 HP가 자꾸 0이하로 떨어지는 버그 발생

    • 분명 프로퍼티 안에 0 이하로 떨어지면 hp를 0으로 초기화해주는 조건문을 넣었는데도, 자꾸 HP가 음수로 떨어지는 버그가 발생했다.
    • 추측: 프로퍼티 Hp가 아닌 변수 hp를 사용해서 코드가 제대로 적용되지 않았던 것 아닐까 싶음.
    • 그래서 변수 hp를 썼던 부분을 전부 프로퍼티 Hp로 바꿔주었는데, 이번엔 어제 일어났던 버그(초기화를 해도 체력이 0에서 바뀌지 않는 버그)가 또 일어났다… 👉2025.02.03 (월)
    • 오류의 진짜 원인: 나는 아래와 같이 프로퍼티에 조건문을 넣어줬는데, 조건 밖에서 value를 넣어주는 코드가 하나도 없었기 때문에 HP가 0으로 고정된 것이었음.
      private float hp;
      public float Hp
      {
          get { return hp; }
          set
          {
              if (value> MaxHP)
              {
                  hp = MaxHP;
              }
              else if(value< 0)
              {
                  hp = 0;
              }
          }
      }
    • 해결: 다음과 같이 코드를 고쳐주니 문제 없이 돌아갔다!
      private float hp;
      public float Hp
      {
          get { return hp; }
          set
          {
              hp = value;
      
              if (hp > MaxHP)
              {
                  hp = MaxHP;
              }
              else if(hp < 0)
              {
                  hp = 0;
              }
          }
      }

📍회고 및 반성

  • 던전을 구현할 때 Event를 만들어서 각 클래스의 메서드를 한 3개쯤 이어주고 싶었는데, 각각 필요한 매개변수들이 달라서 생각만큼 잘 되지 않아서 아쉬웠음. 다음에는 Event를 사용할 수 있을만한 구조로 설계해서 잘 써보고 싶다!
  • 깃허브에 진행상황을 커밋하는 게 처음에는 번거롭게 느껴졌는데, 막상 이렇게 내가 커밋한 목록들을 보니 감회가 새로웠다. 다음에도 개인프로젝트를 진행할 기회가 있다면 그때도 꼭 깃허브를 사용하고 싶음!

0개의 댓글

관련 채용 정보