// 나레이션 초기화 값
string tex = " 139번 훈련병! \n\n 너 이름이 뭐야? \n\n 이름을 입력 하세요... \n\n >>";
char[] texs = tex.ToCharArray();
foreach (char index in texs)
{
Console.Write(index);
Thread.Sleep(100);
}
player.Name = Console.ReadLine();
// 화면 초기화
Console.Clear();
문자열을 Char로 변환하면서 Char배열에 넣은 뒤에 foreach문으로 한글자씩 찍으면서 Thread.Sleep으로 딜레이를 줘서 채팅을 치는것 처럼 나레이션 방식으로 바꿔보았다.
#region 선입력 방지
static void InputPrevention()
{
bool inputPrevent = true;
while (inputPrevent)
{
e = Console.ReadKey(true);
switch (e.Key)
{
case ConsoleKey.Tab:
inputPrevent = false;
break;
default:
break;
}
}
}
#endregion
나레이션이나 게임을 할 때에 Console.ReadKey를 이용하여 받아서 넘기게 하였는데 그 부작용으로 아무키나 막 누르면서 넘길라고 하다보면 선입력이 발생하여 씬이 막 넘어가버리는 경우가 생겼다.
그래서 위와 같은 메서드를 만들어 캡슐화 시켜두어서 선입력 방지가 필요한 곳에 불러서 사용하게 하고 사용한 위에는 Console.WriteLine으로 Tap키를 눌러달라고 쓰게 하도록 했다.
스타트 ~ 메인 커서 선택으로 변경
다른 팀원들의 메서드에 내가 캡슐화를 시켜놨던 메서드들로 번호로 선택하던 방식을 커서를 움직이며 선택하는 방식으로 바꾸었다.
스타트 ~ 메인 메서드 위치 순서대로 변경
메서드들이 진행 순서대로 있지 않고 여기저기 흩어져 있기에 순서대로 옮겼다.
이등병 스토리(Basic) 및 훈련소(TrainingSchool) 텍스트 나레이션 방식으로 변경
추가된 점에 적었던 나레이션 기능을 다른 글을 읽는 메서드들에 적용했다.
스타트 ~ 메인 ~ 일과 텍스트 위치 조정
맨 윗줄은 한줄 띄고 매 시작 글마다 한칸을 띄우고 글을 적자고 통일하여 전체적으로 돌아다니며 코드를 통일시켰다.
Item Class의 Food 공격력 삭제
음식을 먹으면 공격력도 오르는 몇 아이템도 넣으려 했으나 시간이 부족할듯 하여 공격력은 뺏다.
그에 따른 Food Class로 찍어낸 객체들도 수정했다.
전투 메서드 텍스트 보정 및 Cursor선택으로 변경
팀원이 만들어둔 전투 메서드에 번호 선택 방식을 커서 방식으로 바꾸었다.
private static void AttackAction(Character player1, params Enemy[] enemies)
{
// 초기 설정값
int cursor = 0;
bool onScene = true;
string[] text = new string[enemies.Length];
// 파라미터로 받은 몬스터들 텍스트에 추가
for (int i = 0; i < enemies.Length; i++)
{
text[i] += " =" + enemies[i].EnemyName + "=\n";
}
while (onScene)
{
Console.Clear();
Console.WriteLine("\n 어떤 몬스터를 공격하시겠습니까? \n ");
TextChoice(cursor, text);
e = Console.ReadKey();
cursor = CursorChoice(e, cursor, text, ref onScene);
}
int playerDamage = player1.Attack();
enemies[cursor].EnemyHp -= playerDamage;
Console.WriteLine($" \n 플레이어가 {enemies[cursor].EnemyName}에게 {playerDamage}의 데미지를 입혔습니다.");
}
지금 우리의 게임 방식을 보면 처음 Start Scene메서드 부터 시작해서 각 메서드Scene이 끝날 때 마다 계속해서 다른 Scene메서드를 부르는 방식으로 만들어져 있다.
지금까지는 각 Scene 끝이나 조건이 달성되면 다른 Scene을 계속해서 불러 문제를 몰랐다. 하지만 그렇게 Scene을 계속 타고다니다가 다른 Scene을 부르지 않는 Scene을 만났을 때 문제가 발생했다.
★Scene이 끝나면 그 Scene을 호출한 이전 Scene으로 이동하게 된다.★
이러한 성질을 몰랐기에 심각한 오류가 발생한 것이다. Scene에서 Scene을 부르며 가게되면 점점 그 Scene에 Scene을 물어 쌓여가며 게임이 진행되면 진행될수록 콜스택(CallStack)이 쌓이게 되는 것이다.
이러한 성질을 알았다면 코드를 좀 더 깔끔하고 최적화도 잘 진행될수 있게 했을테지만 이미 과제의 시간이 얼마 남지 않았고 너무나 많이 와버렸기에 일단 최소한의 버그만 잡아보려고 했다.
while (true)
{
string space = "";
// 타이머 차감 및 남은 시간 텍스트
time -= 0.1f;
Console.SetCursorPosition(30, 5);
Console.Write($"남은 시간 : {time.ToString("F")}");
// player 위치 표시
Console.SetCursorPosition(0, 1);
for (int i = 0; i < x; i++)
{
space += " ";
}
Console.WriteLine(space + "O");
// 이동 로직
if (Console.KeyAvailable)
{
x++;
Console.ReadKey(true);
}
// 완주시 반복문 정지
if (x >= 80) break;
// 타임 오버시
if (time <= 0)
{
Console.Clear();
Console.WriteLine("완주 실패....");
Thread.Sleep(2000);
Home();
}
Thread.Sleep(10);
}
Console.Clear();
Console.WriteLine("\n 완주 완료!!");
Console.WriteLine("\n 보상 계산중.... 잠시만 기다려주십시오.");
Thread.Sleep(2000);
Console.WriteLine("\n 남은 시간 : {0}", time.ToString("F"));
Console.WriteLine("\n 남은 시간에 따른 보상 ( 보상목록 )");
Console.WriteLine("\n >> Press the \"TAP\" key to proceed <<");
//선입력 방지 메서드
InputPrevention();
Home();
위 코드를 보면 완주에 실패하게 되어 타임오버가 되면 While문이 끝나기도 전에 Home(); 으로 가는 코드가 있다. 그렇기에 위에 설명해놓은 문제가 생기면 다시 Home을 호출한 Scene메서드인 이곳으로 돌아와 저 if문 안에서 왔다갔다 하게 되는 것이다.
while (true)
{
string space = "";
// 타이머 차감 및 남은 시간 텍스트
time -= 0.1f;
Console.SetCursorPosition(30, 5);
Console.Write($"남은 시간 : {time.ToString("F")}");
// player 위치 표시
Console.SetCursorPosition(0, 1);
for (int i = 0; i < x; i++)
{
space += " ";
}
Console.WriteLine(space + "O");
// 이동 로직
if (Console.KeyAvailable)
{
x++;
Console.ReadKey(true);
}
// 완주시 반복문 정지
if (x >= 80)
{
Console.Clear();
Console.WriteLine("\n 완주 완료!!");
Console.WriteLine("\n 보상 계산중.... 잠시만 기다려주십시오.");
Thread.Sleep(2000);
Console.WriteLine("\n 남은 시간 : {0}", time.ToString("F"));
Console.WriteLine("\n 남은 시간에 따른 보상 ( 보상목록 )");
Console.WriteLine("\n >> Press the \"TAP\" key to proceed <<");
break;
}
// 타임 오버시
if (time <= 0)
{
Console.Clear();
Console.WriteLine("완주 실패....");
Console.WriteLine("\n >> Press the \"TAP\" key to proceed <<");
break;
}
Thread.Sleep(10);
}
//선입력 방지 메서드
InputPrevention();
Home();
Scene에서 Scene으로 이동하는 방식을 고치고 싶었지만 시간이 부족하여 위 코드처럼 최소한의 조치를 해두었다. While문 안에 있던 Scene의 이동을 While문이 종료되고 이동하는 방식으로 바꾸었다.
다음 프로젝트 부터는 이번에 경험했던 문제를 기억하고 초반에 기획에 집중하며 틀을 짜볼것 이다.