C#) Team Text RPG 1
새로운 팀프로젝트의 시작이다.
사실 어제 시작했지만, 깃 저장소를 날려먹는 바람에 진행된게 없다.
(아니 없어졌다.)
이번에는 팀으로 Text RPG를 제작한다.
‘혼자 구조짜고, 코드작성하는 법을 경험했으니, 이젠 팀으로 굴러봐라’는 뜻인 것 같다.
와이어프레임

와이어 프레임은 필수 기능을 기반으로 작성했다.
혼자 할때에 비해 전투 개념이 생겼다.
도전과제를 포함하면 던전과 전투에 대한 기능이 엄청 많아졌다.
나는 팀원 한분과 아이템관련된 상점과 인벤토리를 우선 작업하기로 했다.
Item
아이템은 추상 클래스로 작성했다.
아이템 단독으로만 쓰이지는 않을 것, 이라는 판단이 들었기 때문이다.
public abstract class Item
{
protected string? name;
protected string? description;
protected int price;
protected ITEMTYPE type;
public string Name
{
get { return name; }
set { name = value; }
}
public string Description
{
get { return description; }
set { description = value; }
}
public int Price
{
get { return price; }
set { price = value; }
}
public ITEMTYPE Type
{
get { return type; }
set { type = value; }
}
}
프로퍼티 만드는 것은 뭔가 손에 안익는다.
getter, setter 만드는 게 익숙해..
MountableItem
public class MountableItem : Item
{
private int attack;
private int defense;
private bool own;
private bool equip;
public int Attack
{
get { return attack; }
set { attack = value; }
}
public int Defense
{
get { return defense; }
set { defense = value; }
}
public bool Own
{
get { return own; }
set { own = value; }
}
public bool Equip
{
get { return equip; }
set { equip = value; }
}
}
장착 할 수 있는 아이템이다.
무기, 방어구 정도 될것 같다.
PotionItem
public class PotionItem : Item
{
private int count;
private int heel;
public int Count
{
get { return count; }
set { count = value; }
}
public int Heel
{
get { return heel; }
set { heel = value; }
}
}
소비 될 수 있는 아이템이다.
주로 포션이 될것 같다.
StoreManager
internal class StoreManager : IScene
{
// Singleton
private StoreManager() { }
private static StoreManager? instance;
public static StoreManager Instance
{
get
{
if (instance == null)
instance = new StoreManager();
return instance;
}
}
}
IScene이라는 인터페이스를 상속 받아 각각의 매니저를 만든다.
내가 기존에 Scene이라는 추상 클래스를 만든것과 같은 역할을 한다. (팀원이 알려줌)
각 매니저는 싱글톤으로 작성해 서로 보완적인 관계를 가지도록 한다.
Enter
// GameManager에서 접근하는 곳
public void Enter()
{
// StoreScene 진입
StoreScene();
}
다른 메니저에서 Store 기능에 접근 할 때, 반겨주는 메서드다.
입구부터 복잡하면 안되니 간단하게 메서드 하나로 반겨준다.
StoreScene
private void StoreScene()
{
// 다음 Scene 지정
Action nextScene = StoreScene;
bool choose = false;
while (!choose)
{
// StoreScene 출력
DisplayManager.StoreScene(player, items);
int result = UtilManager.PlayerInput(0, 2);
// 나가기 버튼
if (0 == result)
{
Console.WriteLine("debug로비로 간다");
Thread.Sleep(1000);
nextScene = StoreScene;
choose = true;
}
switch (result)
{
case 1: // 구매 페이지 진입
nextScene = BuyItemScene;
choose = true;
break;
case 2: // 판매 페이지 진입
nextScene = SellItemScene;
choose = true;
break;
}
}
nextScene();
}
개인 과제때는, Scene마다 싱글톤을 작성해, Enter, Exit이 비교적 자유로웠다.
팀과제에서는 큰 Manager를 통해, Scene을 내부에 넣고 큰 전환, 작은 전환을 가져가기로 약속했다.
그 방법을 고민 하던 중 나는 함수 포인터를 생각했고, Action을 찾을 수 있었다.
Action 기능은 오늘 처음 사용해 본다.
C++의 함수포인터의 역할을 대체 할 수 있다고 한다.
다음데 깊게 다뤄보겠다.
Case에 따라 Action타입으로 선언된 nextScene에 다음 Scene을 넣어주고, Scene 지정이 끝나면 반복문을 끝내, 다음 Scene으로 진입하도록 설계했다.
BuyItemScene
private void BuyItemScene()
{
// 다음 Scene 지정
Action nextScene = BuyItemScene;
bool choose = false;
while (!choose)
{
// DiplayManager 접근
DisplayManager.StoreBuyScene(player, items);
int result = UtilManager.PlayerInput(0, items.Count() + 1);
// 나가기 버튼
if (0 == result)
{
nextScene = StoreScene;
choose = true;
}
// 아이템 구매 접근
else
{
BuyItem(result);
}
}
nextScene();
}
위와 거의 비슷하다.
입력 값을 아이템 리스트 보다 1개 더 많게 받아, 나가기 버튼을 할당했다.
나머지 입력 값은 아이템 구매로 접근하게 된다.
BuyItem
private void BuyItem(int idx)
{
// 구매 불가
if (items[idx - 1].Own)
{
Console.WriteLine("이미 구매한 아이템입니다.");
Thread.Sleep(1000);
}
// 구매 가능
else
{
// Gold 충분
if (items[idx - 1].Price <= player.gold)
{
items[idx - 1].Own = true;
player.gold -= items[idx - 1].Price;
Console.WriteLine("구매를 완료했습니다.");
Thread.Sleep(1000);
}
// Gold 부족
else
{
Console.WriteLine("Gold가 부족합니다.");
Thread.Sleep(1000);
}
}
}
위에서 인덱스를 받아와, 아이템 구매를 시도한다.
몇 가지 절차를 통해 경우의 수를 나눴다.
etc.
어제 작성한 Git Flow를 활용해 프로젝트를 진행 하고 있다.
깃 컨벤션도 맞춰가며 커밋하느라 커밋 시도량이 절반 이하로 줄게되었다.
한번에 작성한 코드를, 적절히 코드를 나눠가며 커밋하며 컨벤션을 맞추려 노력했다.
물론 팀원들도 같이 노력해준 덕분에, 깃 브런치가 이전에는 볼수 없었던 예쁨이 생겼다.

댓글남기기