카테고리 없음

내일배움캠프 7일차 TIL - C#을 이용한 텍스트 RPG 게임 개발: 던전 시스템 구현

hbks0224 2025. 4. 18. 20:47

드디어.. 끝이다..!

프로젝트 마감일이 다가왔다

오늘은 던전 시스템 구현과 BGM 재생 로직을 개선 했다.

짧지만 알아보자잇

 

던전입장을 안내하는 창이다.

 

 

요구사항은 다음과 같다 일단 던전을 입장하기위해서는 체력이 0이면 안된다는 것을 명심하자!

 

if (GameInfo.Defense < 3) // 권장 방어력보다 낮을때..
{
    Random rand = new Random();
    int clearchance = rand.Next(0, 100); // 0부터 99 랜덤 배출

    Random rand2 = new Random(); // 성공시 감소할 랜덤 체력
    int use_health = rand.Next(20 - ((int)GameInfo.Defense - 3), 36 - ((int)GameInfo.Defense - 3)); // 권장 방어력 +- 에 따라 종료시 체력 소모 반영
    //근데 방어력이 겁나 높아서 숫자가 음수가 되면?

    if (use_health < 0)
    {

        use_health = 0;
    }
    // 체력 소모가 안되게 설정
    Random rand3 = new Random();

    int cleargold = rand.Next((1000 + 1000 * (int)(GameInfo.Attack) / 100), 1000 + 1000 * 2 * (int)(GameInfo.Attack) / 100); //클리어 골드 공격력  ~ 공격력 * 2 의 % 만큼 추가 보상 획득 가능
    Random rand4 = new Random(); //클리어 경험치

    int clearexp = rand.Next((10 + 10 * (int)(GameInfo.Attack) / 100), 10 + 10 * 2 * (int)(GameInfo.Attack) / 100); //클리어 경험치공격력  ~ 공격력 * 2 의 % 만큼 추가 보상 획득 가능


    if (clearchance < 40)  // 0~39 (총 40)이므로 40프로
    {
        string[] failMessages =  // 랜덤 메시지
        {
        "던전 도중 함정에 빠졌습니다...",
        "갑작스러운 몬스터의 습격에 당했습니다!",
        "길을 잃고 탈출하지 못했습니다...",
        "바닥이 무너져 버렸습니다!",
        "덫을 피하지 못해 쓰러졌습니다..."
        };

        int index = rand.Next(failMessages.Length);
        Dialogue.Print(failMessages[index]);
        Thread.Sleep(1000);
        Dialogue.Print("던전 공략에 실패했습니다.");
        Dialogue.Print($"현재 체력이 절반으로 감소했습니다 : {GameInfo.Health} => {GameInfo.Health / 2}");
        GameInfo.Health = GameInfo.Health / 2;
        Thread.Sleep(1000);
        Dungeon();
    }

    else
    {

        string[] successMessages = new string[]
        {
        "당신은 모든 몬스터를 물리쳤습니다!",
        "보스를 처치하고 귀환했습니다!",
        "던전 깊은 곳의 보물을 손에 넣었습니다!",
        "마침내 던전의 비밀을 밝혀냈습니다!",
        "치열한 전투 끝에 살아남았습니다!"
        };
        int index = rand.Next(successMessages.Length);
        Dialogue.Print(successMessages[index]);
        Thread.Sleep(1000);
        Dialogue.Print("던전 공략에 성공했습니다!");
        Console.WriteLine();
        Dialogue.Print("결과");
        if (use_health <= GameInfo.Health)
        {

            Dialogue.Print($"체력이 {use_health}만큼 감소합니다 {GameInfo.Health} => {GameInfo.Health - use_health}");
            GameInfo.Health -= use_health;


        }
        else
        {
            GameInfo.Health = 0;
            Dialogue.Print($"체력이 0이 됐습니다...");


        }

        Dialogue.Print($"{cleargold} 골드를 획득했습니다 {GameInfo.PlayerGold}G => {GameInfo.PlayerGold + cleargold}G");
        Dialogue.Print($"{clearexp} 경험치를 획득했습니다 {GameInfo.EXP}% => {GameInfo.EXP + clearexp}%");

        GameInfo.PlayerGold += cleargold;
        GameInfo.EXP += clearexp;
        LevelSystem.LevelUP();


    }

권장 방어력보다 방어력이 낮을 경우를 구현해보았다.

이 케이스는 실패, 성공 케이스가 존재하기 때문에 두가지 경우를 나눠 코드를 짰다.

성공 케이스는 권장 방어력보다 방어력이 높을때에도 쓸 수 있으니 개꿀이다.

 

40%확률로 실패를 하기위해선 0부터 99 즉 100개의 랜덤 숫자를 변수에 담아 그 숫자가 40보다 작을 경우만 생각하면 40프로이다. 실패시 현재 체력에 절반을 소모하게 했다.

 

성공시 위에 쓰인 조건대로 보상을 얻도록 했다.

 

  Random rand3 = new Random();

  int cleargold = rand.Next((1000 + 1000 * (int)(GameInfo.Attack) / 100), 1000 + 1000 * 2 * (int)(GameInfo.Attack) / 100); //클리어 골드 공격력  ~ 공격력 * 2 의 % 만큼 추가 보상 획득 가능
  Random rand4 = new Random(); //클리어 경험치

  int clearexp = rand.Next((10 + 10 * (int)(GameInfo.Attack) / 100), 10 + 10 * 2 * (int)(GameInfo.Attack) / 100); //클리어 경험치공격력  ~ 공격력 * 2 의 % 만큼 추가 보상 획득 가능

본인은 3개의 던전을 복붙하고 권장 방어력 부분과 던전 이름만 수정했다.

근데 나중에 던전 종류가 늘어나면 이렇게 할 수 없을 거라 생각하니 괜히 이렇게 한듯;;

다른 방법이 있었을텐데 ㅠㅠ;

 

internal class LevelSystem
{

    public static void LevelUP() //레벨업 관리 함수
    {
        int EXPMAX = 100; // 레벨업에 필요한 경험치

        while (GameInfo.EXP >= EXPMAX) {

            //레벨업을 했다면 경험치에서 100을 빼고 레벨up
            GameInfo.PlayerLevel++;
            GameInfo.Attack += 0.5;
            GameInfo.Defense += 1;
            GameInfo.EXP -= EXPMAX;

            Dialogue.Print($"레벨업! {GameInfo.PlayerLevel - 1}레벨 => {GameInfo.PlayerLevel}레벨");
            
        }

    }
}

 

또한 경험치가 100이상이 됐을시 현재 경험치 -100을 하고 레벨을 1 올리는 로직을 구현했다

 

그리고 bgm 재생에 관련된 문젠데..

 

 internal class Bgm
 {
     public static void Playbgm() // bgm 재생
     {
         ThreadPool.QueueUserWorkItem(_ =>
         {
             //String root = AppDomain.CurrentDomain.BaseDirectory;

             // String result = Path.Combine(root, "bgm.mp3");

             // Console.WriteLine(result); 
             WindowsMediaPlayer player = new WindowsMediaPlayer();
             player.settings.setMode("loop", true); // 반복 재생 설정
             //Console.WriteLine(root);

             player.controls.play(); // 재생 시작
             player.settings.volume = 15; //볼륨 15



         });

주석처리된 부분도 포함이다

원래 이렇게 프로젝트의 경로를 입력 받아 bgm파일의 경로를 잡아주고 재생시키게 했는데

프로젝트를 Git에 올리니까 엥??

bgm 파일이 담긴 폴더는 빼고 올라가는 거였다?

 

 

그래서 튜터님에게 호다닥 달려가서 질문을 드렸는데

D:\c#\txtrpg\txtrpg\bin\Debug\net8.0

이게 mp3파일이 담겨있는 경로다. 그중에서 bin 폴더는 빌드와 관련된 폴더라

git에는 업로드 되지 않게 되어있다고 하셨다.

이유는 이거까지 올리면 누구나 내 프로젝트를 바로 빌드해서 사용 할 수 있기 때문? 인 거 같다.

그러면 어쩌지 어쩌지 하다가..

 

!!!

깃에 mp3파일을 직접 업로드하는 방법을 찾았다!!

 

이렇게 하면 구동 환경마다 다른 경로를 신경 쓸 필요도 전혀 없고

고정된 URL만 사용하기 때문에 무조건 mp3를 재생 시킬 수 있다..!

 

인 줄 알았으나... 튜터님이 추가로 한 마디 해주셨다..

코드를 살펴보면 WindowsMediaPlayer를 사용해 노래를 재생시키게 되어있는데

이러면 다른 환경 특히 MAC 환경에서는 구동이 안된다는 것이었다...

그럼 어떻게 해야하지? 싶었는데

젠장!!!! 애초에 어디서든 실행이 가능한 프레임워크에서 프로젝트를 제작 했어야 한다는 것이었다..

크아악!!!

하지만 이미 엎질러진 물..

이미 만들었기때문에 어쩔 수 없이 MAC은 포기하도록... 하겠습니다...

 

이렇게 프로젝트가 완료되었다.

추가로 넣고 싶은 기능들이 산더미였는데

주어진 시간동안 그런걸 하기에는 아직 멀은 거 같다...

내일은 주말이다!! 그치만 일요일에 정처기 실기 시험이 있기때문에..

공부.. 해야겠지?