XR 플밍 - 6. 콘솔 프로젝트 - 시작을 위한 백로그 (4/7)

이형원·2025년 4월 7일
0

XR플밍

목록 보기
36/215

지금까지 배운 내용을 바탕으로, 3일 간의 제작 기간 동안 콘솔 프로젝트를 만들 것이다. 앞으로의 작업에 앞서, 어떤 게임을 만들고 무슨 기능을 구현할 지에 대한 개요부터 짜 보려고 한다.

1. 뭘 만들 거야?

프로젝트의 평가 기준이 있다 보니, 이런 기능 만들어야 겠고, 저런 기능 만들어야 겠고 이런 저런 생각을 하다 보니 도저히 정리가 되지 않을 것만 같았다. 애초에 지금까지 연습삼아 만든 것이 마을 갔다가 필드 갔다가 아이템 사용하고 어쩌고 하는 건데, 이 틀에서 맞춘 게임은 결국 따라한 게임과 다를 바 없다는 생각이 들었기 때문이다.
(그리고 난 그런 전형적인 RPG를 매우 싫어한다.)

그래서, 일단 게임 컨셉을 정하자.

게임 컨셉 자체는 Text RPG로 하고 싶다. 다만 장르를 뭘로 할 것이냐, 라는 생각에 나는 생각난 컨셉이 아래와 같았다.

  1. 방탈출 느낌의 Text RPG 게임 (호감도 기능과 엔딩 루트 구현 등등?)
  2. 스토리형 Text RPG + 퍼즐이 섞인 게임 (최근에 젤다의 전설 스카이워드 소드를 너무 재밌게 해서)
  3. 지금까지 만들었던 전형적인 RPG게임 에 메이플스토리를 버무려버리는 발상

사실 여기서 제일 하고 싶은 건 번호순이고, 방탈출 느낌의 Text RPG를 구현하고 싶다는 열망이 컸다. 다만, 고민인 건 이번 콘솔 프로젝트가 아무래도 포트폴리오 용으로 제작하는 것이다 보니, 방탈출 RPG는 아무래도 다채로운 기능 구현은 어렵지 않을까 하는 생각이 들었다.
(해봤자 인벤토리 사용 기능 정도만 구현할 수 있지 않을까 싶은)

한참을 고민한 끝에 내린 결론은 다음과 같았다.

일단 첫 번째 컨셉으로 만들어 보면서, 정 기능 구현이 애매하다 싶으면 2번으로 틀자.
왠지 초반 컨셉 자체는 1번이랑 2번이랑 겹칠 것 같으니까, 중간에 스토리만 바꾸면 된다.

그래서 컨셉을 방탈출 Text RPG(수틀리면 퍼즐RPG로 바꿀 준비) 로 준비하고 백로그를 써 보기로 했다.

2. 필요한 기능 구현

스토리는 나중에 대충 짜면 되겠지. 우선은 필요한 기능이 뭔지부터 시작해 보자.

2.1. 메인 화면과 씬 전환

Text RPG니까 씬 전환과 텍스트 출력이 되어야만 한다. 내부적으로 들어가는 장면을 제외하고 타이틀 씬과 엔딩 씬을 만들도록 하자.

2.2. 맵

일단 컨셉은 탑 뷰 형식의 맵에서 플레이어가 이동하고, 상호작용을 하는 시스템을 목표로 한다.

2.3. 인벤토리 / 아이템 / 단서

탈출을 위한 아이템, 단서 등을 수집하고 열람할 수 있는 시스템을 구현한다.

2.4. 플레이어와 스텟

구체적인 내용은 정해봐야지 알겠지만, 필수적으로 필요한 건 HP 수치와 정신력 수치이다.

2.5. NPC와 상호작용

1 컨셉으로 만들든, 2 컨셉으로 만들든 일단 NPC의 중요성을 높이는 방향으로 게임을 만들어 보고자 한다.

3. 기능 구현 내용을 좀 더 구체화 해보자.

3.1 메인 화면과 씬 전환

씬은 크게 다음과 같이 나뉜다.

  1. 타이틀 씬, 엔딩 씬

    아마도 게임에서 1회성으로 출력될 가능성이 클 것 같다. (타이틀로 돌아가기 기능을 만들지 않으면)

  2. 맵 씬

    당장 생각하는 맵 규모는 3개까지만 구현하자 인데, 만약 시간이 더 되면 5개까지 구현하자.

  3. 대화 씬

    아무래도 게임 대부분에서 차지하게 되는 씬이 될 것 같다. 사소한 상호작용은 맵에서 출력하되, 스토리에 중점이 되는 부분은 대화 씬으로 따로 빼도록 한다.

3.2 맵

맵에 구현해야 할 내용은 크게 아래와 같다.

  1. 벽 : 플레이어가 이동할 수 없는 영역이다.
  2. 아이템 : 플레이어가 상호작용하면서 얻거나, 사용할 수 있는 물건이다.
  3. 플레이어 : 플레이어 자신의 이동을 구현한다.
  4. NPC : 기본적으로 NPC의 성을 알파벳으로 표기하여 만들 것이며, 특정 위치에 고정되어 있거나 특정 이벤트 이후로 이동하도록 만든다.

3.3 인벤토리 / 아이템 / 단서

인벤토리, 아이템, 단서는 다음과 같은 기능을 가지도록 구현한다.

  1. 인벤토리 : 인벤토리는 굳이 플레이어가 들지 않아도, Game 쪽에서 static으로 들게 구현해도 될 것 같다. 인벤토리는 아이템과 단서를 담을 수 있으며, 각각을 구별하여 담는다.
    아이템은 최대 3개까지만 들고 다닐 수 있으며 단서는 보관 개수에 제한이 없다.

  2. 아이템 : 아이템은 크게 플레이어의 HP와 정신력을 회복하는 포션류와, 탈출에 직접적인 영향을 끼치는 상호작용 아이템으로 구분한다.

  3. 단서 : 단서는 엔딩루트에 영향을 끼치도록 설계한다.(모은 단서의 개수에 따라 엔딩 분기점)

3.4 플레이어와 스텟

플레이어 자체가 가진 기능은 적다. 다만 플레이어는 HP와 정신력을 가지며 해당 스텟의 상태에 따라 선택지의 제약을 받는다.

3.5 NPC와 상호작용

NPC 클래스로 따로 분류를 하여 상호작용 및 호감도 등의 기능을 담도록 하며, 호감도에 따라 엔딩 루트가 갈리거나, 대화 내용이 달라지도록 한다.

  1. 호감도 기능 - 대화 내용, 협력 등의 행동 변화
  2. 스탯은 없으나 NPC마다 가능한 행동을 정의하여 플레이어가 특정 행동을 지시할 수 있도록 구현

기능 구현은 위와 같이 작성하고서, 게임을 만들고자 한다.

4. 도전 백로그

위의 기능을 우선으로 구현하되, 추가로 구현할 수 있을 기능은 아래와 같이 설정하기로 했다.

4.1 제한시간

탈출에 제한시간을 건다. 다만 대화 도중에는 시간이 흐르지 않으며, 맵에 있을 때에만 시간이 흐르도록 구현

4.2 퀘스트 시스템 구현

퀘스트 시스템의 구현이 많이 어려운 편이라는 말을 들었다. 가능하다면 퀘스트 시스템을 구현해 보도록 하자.

5. 이제 정리는 끝났다, 게임 제작의 시작.

프로젝트의 시작일 자체는 내일부터지만, 미리 조금이라도 더 만들어 보고 싶어서 깃의 생성과 기본 시스템 구현 정도만 해 놓기로 했다.

5.1 타이틀 씬과 씬 넘어가기 구현


우선 깃을 만들었다. 게임 제목은 사실 당장 생각나는 게 없어서 Project_Exit으로 만들고 시작해 보기로 했다.

그 다음으로 클래스부터 차근차근 만들어 보기 시작했다.

Scene은 많아질 것 같은 생각에 따로 폴더를 만들어주고, 우선 static으로 선언한 Game과 Base Scene 추상클래스, TitleScene 등을 만들었다.

// Game 클래스
public static class Game
{
    private static Dictionary<string, BaseScene> sceneDic;
    private static BaseScene curScene;

    private static bool gameOver = false;
    public static void Run()
    {
        Start();

        while (gameOver == false)
        {
            Console.Clear();
            curScene.Render();
            curScene.Input();
            Console.WriteLine();
            curScene.Update();
            Console.WriteLine();
            curScene.Result();
        }

        End();
    }

    /// <summary>
    /// 게임의 초기 설정을 진행
    /// </summary>
    private static void Start()
    {
        Console.CursorVisible = false;
        gameOver = false ;

        sceneDic = new Dictionary<string, BaseScene>();
        sceneDic.Add("Title", new TitleScene());

        curScene = sceneDic["Title"];
    }

    /// <summary>
    /// 게임의 마무리 작업 진행
    /// </summary>
    private static void End()
    {

    }
}


// BaseScene 추상클래스
public abstract class BaseScene
{
    public abstract void Render();
    public abstract void Input();
    public abstract void Update();
    public abstract void Result();
}


// TitleScene 자식클래스
public class TitleScene : BaseScene
{
	public override void Render()
	{
		Console.WriteLine("============================");
		Console.WriteLine("        Project Exit     ");
		Console.WriteLine();
		Console.WriteLine("               시나리오 :"   );
		Console.WriteLine("                   by xxx");
		Console.WriteLine("============================");
		Console.WriteLine();
		Console.WriteLine("Press Any Key to Continue...");
	}
    
	public override void Input()
	{
		Console.ReadKey(true);
	}

	public override void Update()
	{

	}

	public override void Result()
	{

	}
}

우선 여기까지는 기존에 구현했던 방식으로 했다.

의도했던 대로 잘 구현되고 있는 것을 확인했다.
이제 다음 씬부터는 이전까지는 않았던 새로운 내용을 구현해 볼 차례다.

5.2 X키로만 출력되는 텍스트 Util 구현

일단 다음 씬을 만들기 위해서 PrologueScene을 만들고, 아래와 같이 작성했다.

Console.WriteLine("당신은 어둠 속에서 눈을 떴다.");
Console.ReadKey(true);
Console.WriteLine("이곳은 어둡고 퀴퀴한 냄새가 나고");
Console.ReadKey(true);
Console.WriteLine("춥고 딱딱한 바닥에 몸서리치며");
Console.ReadKey(true);
Console.WriteLine("깨어납니다.");
Console.ReadKey(true);

(시나리오는 아직 안 짜놔서 그냥 아무렇게나 텍스트를 쳤다 내용은 무시하자.)
저렇게 ReadKey를 사이에 넣은 이유는, 텍스트를 한 줄 씩 넘어가게 하려는 기능을 넣어보고자 한 것이다.
하지만 저렇게 만들고 보니 코드가 지저분하고, 또 막상 생각해보니 키를 하나로 고정시켜서 그 키만 누르면 넘어가게 하는 게 낫겠다는 생각이 들었다.
그래서 유틸 기능을 하나 만들어 보기로 했다.

public static class Util
{
    static ConsoleKey input;
    public static void XKeyText(string text)
    {
        input = Console.ReadKey(true).Key;
        switch(input)
        {
            case ConsoleKey.X:
                Console.WriteLine(text);
                break;
        }    
    }
}

처음엔 이렇게 구현해 보았다. Switch문을 사용하여 X키 입력이 들어왔을 때 텍스트가 출력되도록 하였다. 하지만 이렇게 구현하니 다른 문제가 생겼다. X키를 누르다가 다른 키를 누르면, 지금까지 출력됐던 텍스트가 다 지워지는, 그러니까 input으로 바로 넘어가는 현상이 발견된 것이다.

이걸 방지하기 위해선 어떡해야 할까, 고민하다가 반복문에 넣고 조건이 맞으면 반복문을 깨고 Text를 출력하고, 아니면 반복문을 못 빠져나가게 하면 구현할 수 있겠다 생각했다.
위 Util 코드를 아래와 같이 수정하고 텍스트를 써 보았다.

// X키를 눌러야지 넘어가는 텍스트를 구현
public static void XKeyText(string text)
{           
    while(true)
    {
        input = Console.ReadKey(true).Key;
        if (input == ConsoleKey.X)
        {
            Console.WriteLine(text);
            break;
        }
        else // X키 외의 키를 누르면 무반응으로 설정
        {
            continue;
        }
    }                      
}

이렇게 작성하고서 콘솔을 작동시키니 원하는대로 기능이 작동하는 것을 확인했다.

profile
게임 만들러 코딩 공부중

0개의 댓글