Unity 개발 일지/게임 기획

[팀프로젝트] Text RPG 만들기

ohty20012 2025. 4. 21. 22:00

팀 프로젝트로 Text RPG를 만들기 시작했다.

 

게임은 다음 7가지 페이즈로 구분되어 있다.

  • 시작 화면
  • 로비
  • 상태보기
  • 인벤토리
  • 상점
  • 던전입장
  • 휴식

추가적으로 구현하면 좋은 기능으로는 다음과 같다.

  • 전투 화면
  • 치명타
  • 회피
  • 스킬
  • 레벨업
  • 추가 보상

 

 

오늘 구현한 내용은 전투 화면이다.

 

 

 

 

< 코드 >

더보기
using Spectre.Console;
using Starfall.IO.CUI;
using Starfall.PlayerService;

// 임시 몬스터 클래스
struct Monster
{
    public string name = "Monster";
    public int level = 1;
    public float hp = 100;
    public float atk = 0;
    public float def = 5;

    public Monster(string name, int level, float hp, float atk, float def)
    {
        this.name = name;
        this.level = level;
        this.atk = atk;
        this.def = def;
        this.hp = hp;
    }

    public bool IsAlive => hp > 0;
    public void Dead() => Console.WriteLine($"{name}이 죽었습니다");
}

namespace Starfall.Core.Classic
{
    public class ClassicBattle()
    {
        public void StartBattle(Player player)
        {
            // 세 마리 몬스터 생성
            var monsters = new List<Monster>
        {
            new("미니언", 2, 15, 5, 0),
            new("공허충", 3, 10, 9, 0),
            new("대포미니언", 5, 25, 8, 0)
        };

            while (true)
            {
                Console.Clear();
                AnsiConsole.MarkupLine("Battle!!\n");

                // 몬스터 목록 출력
                for (int i = 0; i < monsters.Count; i++)
                {
                    var m = monsters[i];
                    var hpText = m.IsAlive ? $"HP {m.hp}" : "Dead";
                    AnsiConsole.MarkupLine($"{i + 1} Lv.{m.level} {m.name}  {hpText}");
                }

                AnsiConsole.MarkupLine($"\n내 정보\nLv.{player.level} {player.name} {player.job}\nHP {player.TrueHp}/{player.hp}\n");

                // 모든 몬스터가 죽었으면 전투 종료
                if (monsters.All(m => !m.IsAlive))
                {
                    AnsiConsole.MarkupLine("\n모든 몬스터를 처치했습니다! 전투 종료.");
                    MenuUtil.OpenMenu("확인");
                    break;
                }

                // 공격할 대상 선택
                var options = new List<string>();
                foreach (var m in monsters)
                    options.Add($"{m.name} 공격");

                options.Add("0. 나가기");

                var choice = MenuUtil.OpenMenu([.. options]);

                var target = monsters[choice];

                if (!target.IsAlive)
                {
                    AnsiConsole.MarkupLine($"\n이미 쓰러진 {target.name}은 공격할 수 없습니다.");
                }
                else
                {
                    target.hp -= player.TrueAtk;
                    AnsiConsole.MarkupLine($"\n{target.name}에게 {player.TrueAtk}의 데미지를 입혔습니다!");
                    if (!target.IsAlive)
                        AnsiConsole.MarkupLine($"{target.name}을 처치했습니다!");
                }

                MenuUtil.OpenMenu("다음");
            }
        }
    }
}

 

 

난이도가 많이 높지는 않은 부분을 제작했기에 크게 막히는 부분은 없었지만

 

초반에 어려웠던 부분을 몇 가지 소개하자면

 

 

< 1. 외부 라이브러리 해석>

 

이 프로젝트에서는 여러 개의 외부 라이브러리를 사용하는데,

 

다른 사람이 추가한 라이브러리라서 해석하고 의도를 파악하는 게 꽤 힘들었다.

 

 

< 2. 메서드를 어떻게 구현할 것인가 >

 

메서드를 구현할 때 다음 고민을 하는 시간이 가장 길었다.

  • 어떤 파라미터를 받아올 것인가
  • 반환 값을 무엇으로 할 것인가
  • 기존 코드와 어떻게 상호작용 할 것인가

 

 

< 외부 라이브러리 해석 팁 >

  1. 함수의 이름, 매개변수, 리턴 값을 먼저 보기
  2. 작은 예제부터 실행해보기
  3. 전반적인 구조 파악

순으로 진행하는게 이해하는데 도움이 많이 됐다.