[TIL] C# - 콘솔창 꾸미기 , UML

MINO·2024년 4월 30일
0
post-thumbnail

2024-04-30

본격적인 기능 구현에 돌입하여 많은 코드를 작성하고, 예외 상황도 많이 발생하였다.

상점에서 아이템을 구매하지 않고 나올 때, if 문의 범위를 잘못 설정하여 IndexOutOfRangeException 예외가 발생하였다.
코드에 주석을 달아가며, 차근차근 코드의 흐름을 살펴보니 숫자값을 입력 받아 상점의 물품 리스트를 확인하는 곳에서 -1 을 전달 받아 발생한 오류였다.

오류가 발생했을 때, 당황하지말고 작성한 코드의 흐름과 { } 의 범위를 잘 살펴보도록 하자.


UML

프로젝트의 규모가 조금씩 커지다보니, 클래스의 사용이 많아졌다.

  • Player 클래스를 상속 받은 Warrior 와 Mage 클래스
  • Enemy 클래스를 상속 받은 Wolf, Ork .. 클래스
  • 이름과 효과, 설명, 가격 등의 변수를 가지고 있는 Item 클래스

복잡한 시스템의 설계,구조 를 이해하기 위해 UML 다이어그램 (Unified Modeling Language) 를 사용해보자.

아직 상속, 인터페이스, 추상 클래스를 자유롭게 다루지 못하기 때문에,
UML 을 활용하며 클래스와 먼저 친해져야 할 필요가 있다.

UML - 참고 티스토리


사용 예시

  • Player 클래스를 상속 받은 Warrior 와 Mage 클래스

  • 아직 구현하진 않았지만, 임의로 정의한 Quest 클래스의 틀

  • 세은님이 맡으신 Item 클래스

코드 예시

  • Player 클래스를 상속 받은 Warrior 와 Mage 클래스
class Player
{
    public string Name { get; }
    public int Job { get; set; } = 0;
    public int Level { get; } = 1;
    public int Atk { get; set; } = 5;
    public int Def { get; set; } = 5;
    public int Hp { get; set; } = 100;
    public int Mp { get; set; } = 50;
	public int Gold { get; set; } = 1500;
	public int Exp { get; set; } = 

	public Player(string name) // 생성자
	{
    	Name = name;
	}
    
	public void StatusMenu() {...}
	public bool Critical() {...}
	public bool Avoid() {...}
	
}

class Warrior : Player
{
	public Warrior(string name) : base(name) // 생성자
	{
    	Job = 1;
    	Atk = 8; // 전사의 공격력 설정
    	Def = 10; // 전사의 방어력 설정
	}
    
	public int Alpha_Strike() {...}
	public int Double_Strike() {...}
}

class Mage : Player
{
	public Mage(string name) : base(name)
	{
    	Job = 2;
    	Atk = 12; // 마법사의 공격력 설정
    	Def = 6; // 마법사의 방어력 설정
	}
	
    public int Energy_Bolt() {...}
    public int Thunder_Bolt() {...}
}

UML 을 참고하며 클래스를 구현하니
빠진 메서드나 변수는 없는지, 상속 관계는 잘 이루어져 있는지 확인하기 쉽다.


콘솔창 꾸미기

C# Console 을 통해, 게임의 모든 내용을 전달해야하다 보니 표현할 수 있는 것이 한정적이라
게임의 완성도가 떨어져보였다.

나름대로 장면의 변환이나 중요한 텍스트의 경우,
Console.ForegroundColor 를 통해 색상을 지정해주었지만 부족해보여
다음의 메서드를 활용해 약간의 애니메이션을 만들어보았다.

체력이 50 일 때, 휴식하기를 통하여 최대 체력으로 채워주는 장면을
동적으로 보이게 만들어보았다.


Console.SetCursorPosition( )

포지션에 커서를 위치시킨다.

public static void SetCursorPosition (int left, int top);

매개 변수 : left(커서의 열 위치), top (커서의 행 위치)
left 의 경우, 0 부터 시작하여 왼쪽에서 오른쪽으로 번호가 매겨짐
top 의 경우, 0 부터 시작하여 위쪽에서 아래쪽으로 번호가 매겨짐


Thread.Sleep( )

지정된 시간(ms) 동안 현재 스레드를 일시 중단한다.

public static void Sleep (int millisecondsTimeout);

매개 변수 : millisecondsTimeout (스레드가 일시 중단되는 ms 수)


구현 코드

while(player.Hp < 100) // 100 대신 max_hp 로 수정 필요
{
    Thread.Sleep(50);
    player.Hp++;
    Console.SetCursorPosition(12, 8);
    Console.Write($"{player.Hp}");
}

Thread.Sleep(200);
player.Gold -= 500;      
Console.WriteLine($"\n\n남은 골드 : {player.Gold}");
ConsoleUtility.PromptReturn();

결과물

딱딱해보이는 Text형 게임이지만,
while 문과 Thread.Sleep , 커서 설정 메서드를 통해
체력이 점점 증가하는 것처럼 보이게 만들었다.


TIL 마무리

팀 프로젝트를 진행하다보니, 팀원들간의 코딩 스타일이 달라
UI 와 구조를 통일화 하는데 생각보다 시간이 오래 걸렸다.

캠프에 참여하는 모든 인원이 같은 주제의 프로젝트를 진행하다보니
애착이 가지 않을 거라고 생각했지만,
시간과 몸을 더 갈아서 남들보다 더 재밌고, 볼 것이 많은 게임을 만들고 싶다는 생각이 들었다.

profile
안녕하세요 게임 개발하는 MINO 입니다.

0개의 댓글