TextRPG 개인과제를 팀과제로 구현하기로 했다.

아직 개인학습이 끝나지 않은 분들도 계셔서 간단한 사항만 결정하고 금요일에 게임 컨셉을 정하고 역할 분담을 하기로 했다.

 

<회의 사항>

스크럼을 오전, 오후 2회로 늘리고 개인학습으로 대화를 많이 하지 않아서 친해지는 시간을 갖기로 했다.

맥 유저와 윈도우 유저 확인하고 발표와 영상 등을 정했다. 깃을 써보지 않은 분들이 많아서 목요일 저녁에 한 번씩 커밋 연습해보는 시간을 갖는 것이 좋을 것 같다.

 

게임 방향성은 팀원분이 추천해주신 참고 할 만한 게임인 다크드래곤을 찾아보고, TRPG 형식으로 주사위를 굴려 공격하는 형식은 어떨까 생각 중이다.

<오늘의 계획>

1. 기능 수정

2. 콘솔 꾸미기

 

  • 기능 수정

인트로 멘트가 한 글자씩 출력되면 좋을 것 같아서 while문과 Thread.Sleep()을 통해 0.05초에 한 글자씩 나오도록 기본설정을 하고, 아무 키를 입력했을 때 스킵되도록 했다.Console.KeyAvailable은 bool값으로 어떤 키를 눌렀을 때 true를 출력한다. 이를 이용하여 값이 true가 되면 Thread.Sleep()의 속도를 다시 0으로 만들어주어 전체 멘트가 나오도록 했다.이 기능은 자주 사용할 것 같아서 메서드로 만들어주었다.

// 한글자씩 출력
static void OutputTxt(string txt) // string = Char(문자) 배열
{
    Console.ForegroundColor = ConsoleColor.Cyan;

    // 아무 키나 눌렀을 때 스킵
    int speed = 50;
    int txtCount = 0; // 글자수
    while (txtCount != txt.Length) // txt 글자수가 끝까지 나올 때까지
    {
        if (Console.KeyAvailable) // 아무 키나 눌렸을 때 true
        {
            speed = 0;
            Console.ReadKey(true);
        }
        Console.Write(txt[txtCount]); // 글자를 하나하나 가져올 인덱스
        Thread.Sleep(speed);
        txtCount++;
    }
}

// 적용
static void DisplayGameIntro()
{
	string startTxt = "스파르타 마을에 오신 여러분 환영합니다.\n이곳에서 던전으로 들어가기 전 활동을 할 수 있습니다.\n";
	OutputTxt(startTxt);
}

Console.Readkey( ) : 사용자가 눌린 키 한 문자 정보를 리턴하는 메소드

Console.KeyAvailable : 키 입력값의 참거짓 여부

 

  • 콘솔 꾸미기

콘솔 꾸미기 명령어

// 콘솔 배경
Console.BackgroundColor = ConsoleColor.색상;
Console.Clear(); // 화면 지우기

// 글씨색 변경
Console.ForegroundColor = ConsoleColor.색상;

// 글씨색 기본색으로 되돌리기
Console.ResetColor();

// 콘솔창 이름 설정
Console.Title = "콘솔창";

 

 

<추가>

- 코드에 필요한 클래스를 별도의 파일로 만들고 분리해보기

- Readme 작성하기

 

<마치며>

C#에 좀 더 친숙해지는 것에 중점을 맞췄어야했는데 많은 기능을 구현하고 싶은 욕심에 새로운 메서드를 찾아보고 탐구하는 것에 너무 시간을 할애했던 것 같다. 잘하는 분들은 시간이 남았기 때문에 여러 가지 추가기능을 구현했음을 항상 유의하고 초보자인 나는 문법 위주로 공부해야겠다.

 

 

<구상 및 설계>

기본적으로 게임 시작화면과 선택지를 눌렀을 때, 캐릭터의 상태를 볼 수 있는 상태 보기창과 인벤토리 창으로 구성할 예정이다.

능력이 된다면 던전까지 구현하고 싶지만 시간과 능력 부족으로 팀 프로젝트 때 함께 구현해야할 것 같다.

 

게임 시작

- 1. 상태 보기

- 2. 인벤토리 - 1. 장착 관리

- 3. 상점

- 4. 던전 입장

 

<구현>

게임 시작

// 선택지
static int CheckValidInput(int min, int max)
{
    while (true)
    {
        string input = Console.ReadLine();

        bool parseSuccess = int.TryParse(input, out var ret);
        if (parseSuccess)
        {
            if (ret >= min && ret <= max)
                return ret;
        }

        Console.WriteLine("잘못된 입력입니다.");
    }
}

// 메인화면
static void GameLogo()
{
    Console.WriteLine("= Sparta Dungeon =");
    Console.WriteLine("1. 게임시작");
    Console.WriteLine("0. 나가기");
    Console.WriteLine();
    Console.WriteLine("원하시는 행동을 입력해주세요.");
    Console.Write(">> ");

    int input = CheckValidInput(0, 1);
    switch (input)
    {
        case 0:
            break;
        case 1:
            DisplayGameIntro();
            break;
    }
}

// 스타트
static void DisplayGameIntro()
{
    Console.Clear();
    Console.WriteLine("==================================================");
    Console.WriteLine("스파르타 마을에 오신 여러분 환영합니다.\n이곳에서 던전으로 들어가기 전 활동을 할 수 있습니다.");
    Console.WriteLine("==================================================");
    Console.WriteLine();
    Console.WriteLine("1. 상태 보기\n2. 인벤토리\n0. 메인화면");
    Console.WriteLine();
    Console.WriteLine("원하시는 행동을 입력해주세요.");
    Console.Write(">> ");

    int input = CheckValidInput(0, 2);
    switch (input)
    {
        case 0:
            Console.Beep();
            Main();
            break;
        case 1:
            DisplayMyInfo();
            break;
        case 2:
            DisplayInventory();
            break;
    }
}

 

상태 보기

class Program
{
	private static Character player;
    
    // 메인
    static void Main(string[] args)
    {
        GameDataSetting();
        DisplayGameIntro();
    }
    
    // 각종 데이터
    static void GameDataSetting()
    {
        // 캐릭터 정보 세팅
        player = new Character("Chad", "전사", 1, 10, 5, 100, 1500);

        // 아이템 정보 세팅
    }

    static void DisplayMyInfo()
    {
        Console.Clear();
        Console.Title = "= Information =";

        ChooseTextColor("= 상태 보기 =");
        LineTextColor("캐릭터의 정보가 표시됩니다.");
        Console.WriteLine();
        StatTextColor("Lv. ", player.Level.ToString("00")); // 00, 07 등 한자릿수도 두자릿수로 표현하기 위해 string 타입으로 변환
        Console.WriteLine();
        Console.WriteLine("{0} ( {1} )", player.Name, player.Job);
        StatTextColor("공격력 : ", player.Atk.ToString());
        Console.WriteLine();
        StatTextColor("방어력 : ", player.Def.ToString());
        Console.WriteLine();
        StatTextColor("체 력 : ", player.Hp.ToString());
        Console.WriteLine();
        StatTextColor("Gold : ", player.Gold.ToString());
        Console.WriteLine();
        Console.WriteLine();
        ChooseTextColor("0. 나가기");
        Console.WriteLine();
        Console.WriteLine("원하시는 행동을 입력해주세요.");
        Console.Write(">> ");

        int input = CheckValidInput(0, 0);
        switch (input)
        {
            case 0:
                DisplayGameIntro();
                break;
        }
    }
}

// 플레이어의 캐릭터 상태 클래스
public class Character
{
    public string Name { get; }
    public string Job { get; }
    public int Level { get; }
    public int Atk { get; }
    public int Def { get; }
    public int Hp { get; }
    public int Gold { get; }

    public Character(string name, string job, int level, int atk, int def, int hp, int gold)
    {
        Name = name;
        Job = job;
        Level = level;
        Atk = atk;
        Def = def;
        Hp = hp;
        Gold = gold;
    }
}

 

인벤토리

class Program
{
	private static Character player;
	private static Item[] items;
    
    // 각종 데이터
    static void GameDataSetting()
    {
        // 캐릭터 정보 세팅
        player = new Character("Chad", "전사", 1, 10, 5, 100, 1500);

        // 아이템 정보 세팅
        items = new Item[10]; // 최대 아이템 10개
        AddItem(new Item("무쇠갑옷", "무쇠로 만들어져 튼튼한 갑옷입니다.", 0, 0, 5, 0));
        AddItem(new Item("낡은 검", "쉽게 볼 수 있는 낡은 검입니다.", 1, 2, 0, 0));
        AddItem(new Item("고양이 수염", "고양이 수염은 행운을 가져다 줍니다. 야옹!", 1, 7, 7, 7));
    }

    // 아이템 추가
    static void AddItem(Item item)
    {
        if (Item.ItemCount == 10) return; // 아이템이 꽉차면 아무일도 일어나지 않는다
        items[Item.ItemCount] = item; // 0개 -> items[0], 1개 -> items[1] ...
        Item.ItemCount++; // AddItem이 될 때마다 ItemCount가 올라간다
    }

    // 인벤토리
    static void DisplayInventory()
    {
        Console.Clear();
        Console.Title = "= inventory =";

        Console.WriteLine("인벤토리");
        Console.WriteLine("보유 중인 아이템을 관리할 수 있습니다.");
        Console.WriteLine();
        Console.WriteLine("[아이템 목록]");

        for (int i = 0; i < Item.ItemCount; i++)
        {
            items[i].ItemStat();
        }

        Console.WriteLine("");
        Console.WriteLine("1. 장착 관리\n0. 나가기");
        Console.WriteLine();
        Console.WriteLine("원하시는 행동을 입력해주세요.");
        Console.Write(">> ");

        int input = CheckValidInput(0, 1);
        switch (input)
        {
            case 0:
                DisplayGameIntro();
                break;
            case 1:
                DisplayerEquip();
                break;
        }
    }
}

// 아이템 클래스
public class Item
{
    public string Name { get; }
    public string Description { get; }
    public int Type { get; }
    public int AtkOption { get; }
    public int DefOption { get; }
    public int HpOption { get; }
    public bool IsEquipped { get; set; }

    public static int ItemCount = 0; // static을 붙임으로 Item이라는 클래스에 귀속된다

    public Item(string name, string description, int type, int atkOption, int defOption, int hpOption, bool isEquipped = false)
    {
        Name = name;
        Description = description;
        Type = type;
        AtkOption = atkOption;
        DefOption = defOption;
        HpOption = hpOption;
        IsEquipped = isEquipped;
    }
	
    // 아이템 착용여부
    public void ItemStat(bool wearItem = false, int index = 0)
    {
        Console.Write("- ");
        if (IsEquipped)
        {
            Console.Write("[");
            Console.Write("E");
            Console.Write("]");
        }
        Console.Write(Name);
        Console.Write(" | ");

        if (AtkOption != 0) Console.Write($"AtkOption {(AtkOption >= 0 ? "+" : "")}{AtkOption} "); // 삼항연산자
        if (DefOption != 0) Console.Write($"DefOption {(DefOption >= 0 ? "+" : "")}{DefOption} "); // 옵션이 0이 아니라면 옵션수치를 내보내라
        if (HpOption != 0) Console.Write($"HpOption {(HpOption >= 0 ? "+" : "")}{HpOption} "); // [조건 ? 참 : 거짓]

        Console.Write(" | ");

        Console.WriteLine(Description);
    }
}

 

장착관리

// 장착 관리
static void DisplayerEquip()
{
    Console.Clear();
    Console.Title = "= Item Equip =";

    Console.WriteLine("인벤토리 - 장착 관리");
    Console.WriteLine("보유 중인 아이템을 관리할 수 있습니다.");
    Console.WriteLine();
    Console.WriteLine("[아이템 목록]");
    for (int i = 0; i < Item.ItemCount; i++)
    {
        items[i].ItemStat(true, i + 1);
    }
    Console.WriteLine();
    Console.WriteLine("0. 나가기");
    Console.WriteLine();
    Console.WriteLine("원하시는 행동을 입력해주세요.");
    Console.Write(">> ");

    int input = CheckValidInput(0, Item.ItemCount);
    switch (input)
    {
        case 0:
            DisplayInventory();
            break;
        default:
            ToggleEquipStatus(input - 1); // 유저가 입력하는건 1, 2, 3...  실제 배열에는 0, 1, 2...
            DisplayerEquip();
            break;
    }
}

// 장비 장착 여부
private static void ToggleEquipStatus(int index)
{
    items[index].IsEquipped = !items[index].IsEquipped; // ! : 불형의 변수를 반대로 만들어주는 것
}

// 장비 능력치 더하기
private static int itemStatSumAtk()
{
    int sum = 0;
    for (int i = 0; i < Item.ItemCount; i++)
    {
        if (items[i].IsEquipped) sum += items[i].AtkOption;
    }
    return sum;
}
private static int itemStatSumDef()
{
    int sum = 0;
    for (int i = 0; i < Item.ItemCount; i++)
    {
        if (items[i].IsEquipped) sum += items[i].DefOption;
    }
    return sum;
}
private static int itemStatSumHp()
{
    int sum = 0;
    for (int i = 0; i < Item.ItemCount; i++)
    {
        if (items[i].IsEquipped) sum += items[i].HpOption;
    }
    return sum;
}

 

 

+ Recent posts