
SingleTonpublic class Singleton
{
private Stack<string> _script;
private static Singleton instance
public static Singleton Instance
{
get { return instance; }
set { instance = value; }
}
private Singleton()
{
_script = new Stack<string>();
}
public static Singleton GetInstance
{
if(instance == null)
{
instance = new Singleton();
}
return instance;
}
public void Talk()
{
_script.Push("main");
while(_script.Count > 0)
{
switch(_script.Peek())
{
case "main" :
Main();
break;
case "sub" :
Sub();
break;
}
}
}
private void Main()
{
if(true)
{
_script.Push("sub");
}
else
{
_script.Pop();
}
}
private void Sub()
{
if(true)
{
//todo : 분기 메뉴 추가
}
else
{
_script.Pop();
}
}
}
위의 코드는 게임 속 특수 NPC의 클래스의 구성을 간단하게 구현한 것이다. 특수 NPC의 경우 하나의 인스턴스만을 가지고, 스크립트에 따른 대화도 가능한데 이를 싱글톤과 스택을 활용하여 나타냈다. 확실히 하나의 형식을 만들어놓아서 그런지 NPC 클래스 생성에 부담이 없는게 큰 장점인 것 같다.
Util이번에 프로젝트를 진행하면서 사용하기 위해 만든 유틸 기능을 간단히 적어보려한다.
public static void PrintWordLine(string context,
ConsoleColor textColor = ConsoleColor.White, int delay = 60)
{
Console.ForegroundColor = textColor;
for(int i = 0; i < context.Length; i++)
{
Console.Write(context[i]);
Thread.Sleep(delay);
}
Console.ResetColor();
}
한 글자씩 출력하기 위해 만든 기능이다. 색상과 딜레이 시간을 조절할 수 있게 했다.
public static void PrintWaiting()
{
Console.CursorVisible = false;
int left;
int right;
(left, right) = Console.GetCursorPosition();
Console.SetCursorPosition(left + 10, right + 1);
while (!Console.KeyAvailable)
{
PrintWord("▼", ConsoleColor.DarkYellow, 400);
Console.Write("\b \b");
Thread.Sleep(400);
}
Console.ReadKey(true);
}
사용자의 입력을 기다릴 때 스크립트 아래에 삼각형(▼)이 깜빡거리도록하여 간접적으로 입력을 요구하도록 만들었다.
public static void PrintSideTriangleForNum(int x, int y,
ref int decision, params int[] number)
{
int left;
int right;
decision = x + 1;
int b = y + 1;
ConsoleKey newInput = ConsoleKey.Add;
for (int i = 0; i < number.Length; i++)
{
Console.SetCursorPosition(x + i, y);
Console.WriteLine(number[i]);
}
Console.SetCursorPosition(x, y + 1);
Console.Write("▲");
newInput = Console.ReadKey().Key;
(left, right) = Console.GetCursorPosition();
while (newInput != ConsoleKey.Enter)
{
if (left - 1 <= x && (left - 1 + number.Length - 1) > x
&& newInput == ConsoleKey.RightArrow)
{
Console.Write("\b");
Console.Write(" ");
Console.SetCursorPosition(x += 1, y + 1);
Console.Write("▲");
}
else if (left - 1 < x && (left - 1 + number.Length - 1) >= x
&& newInput == ConsoleKey.LeftArrow)
{
Console.Write("\b");
Console.Write(" ");
Console.SetCursorPosition(x -= 1, y + 1);
Console.Write("▲");
}
else if (newInput == ConsoleKey.UpArrow)
{
Console.SetCursorPosition(decision, b - 1);
Console.Write("\b");
Console.Write(" ");
Console.Write("\b");
if (number[decision - left] + 1 < 10)
{
Console.Write(number[decision - left] + 1);
number[decision - left] += 1;
}
else if (number[decision - left] + 1 == 10)
{
Console.Write(0);
number[decision - left] = 0;
}
Console.SetCursorPosition(decision, b);
}
else if (newInput == ConsoleKey.DownArrow)
{
Console.SetCursorPosition(decision, b - 1);
Console.Write("\b");
Console.Write(" ");
Console.Write("\b");
if (number[decision - left] - 1 >= 0)
{
Console.Write(number[decision - left] - 1);
number[decision - left] -= 1;
}
else if (number[decision - left] - 1 < 0)
{
Console.Write(9);
number[decision - left] = 9;
}
Console.SetCursorPosition(decision, b);
}
(decision, b) = Console.GetCursorPosition();
newInput = Console.ReadKey().Key;
}
}
숫자를 입력할 때 단순히 입력하는 것이 아닌, 각 자릿수를 좌우 방향키로 이동하며 위 아래 방향키로 숫자를 조절하는 기능이다. 입력을 그냥 받는 것이 밋밋해서 구현해보았다.
public static void PrintTriangle(int x, int y,
ref int decision, params string[] message)
{
int left;
int right;
int a;
for (int i = 0; i < message.Length; i++)
{
Console.SetCursorPosition(x + 1, y + i);
Console.WriteLine(message[i]);
}
Console.SetCursorPosition(x, y);
Console.Write("▶");
ConsoleKey newInput = Console.ReadKey().Key;
(left, right) = Console.GetCursorPosition();
while (newInput != ConsoleKey.Enter)
{
if (right <= y && (right + message.Length - 1) > y
&& newInput == ConsoleKey.DownArrow)
{
Console.Write("\b");
Console.Write(" ");
Console.SetCursorPosition(x, ++y);
Console.Write("▶");
}
else if (right < y && (right + message.Length - 1) >= y
&& newInput == ConsoleKey.UpArrow)
{
Console.Write("\b");
Console.Write(" ");
Console.SetCursorPosition(x, --y);
Console.Write("▶");
}
(a, decision) = Console.GetCursorPosition();
newInput = Console.ReadKey().Key;
}
}
선택지가 나올 때 오른쪽에 삼각형(▶)을 함께 출력하고 삼각형의 위치를 위 아래 방향키로 조절하여 선택할 수 있도록 구현했다. 마찬가지로 단순히 입력 받는게 밋밋해서 구현해보았다.
public static void PrintSideTriangle(int x, int y,
ref int decision, params string[] message)
{
int left;
int right;
int b = 0;
for (int i = 0; i < message.Length; i++)
{
Console.SetCursorPosition(x + 1 + 10 * i, y);
Console.WriteLine(message[i]);
}
Console.SetCursorPosition(x, y);
Console.Write("▶");
ConsoleKey newInput = Console.ReadKey().Key;
(left, right) = Console.GetCursorPosition();
while (newInput != ConsoleKey.Enter)
{
if (left - 1 <= x && (left - 1 + (message.Length - 1) * 10) > x
&& newInput == ConsoleKey.RightArrow)
{
Console.Write("\b");
Console.Write(" ");
Console.SetCursorPosition(x += 10, y);
Console.Write("▶");
}
else if (left - 1 < x && (left - 1 + (message.Length - 1) * 10) >= x
&& newInput == ConsoleKey.LeftArrow)
{
Console.Write("\b");
Console.Write(" ");
Console.SetCursorPosition(x -= 10, y);
Console.Write("▶");
}
(decision, b) = Console.GetCursorPosition();
newInput = Console.ReadKey().Key;
}
}
위에서 설명한 선택 보조 삼각형 출력의 가로 버전이다. 선택지가 한 줄로 주어졌을 때 선택지 앞으로 삼각형(▶)이 이동하여 선택할 수 있도록 하였다.