01
15

과정명 : 내일배움캠프 Unity 게임개발 3기

전체진행도 : 16일차

부분진행도 : Chapter2.2 - 5일차

작성일자 : 2024.01.15(월)

개발일지 목록 : 클릭


1. 진행중인 과정에 대해

콘솔 던전 RPG 게임 팀 과제의 개발부분은 오늘 마무리되었다. 큰 문제가 나오지 않는다면, 내일 발표에 관해서 회의를 진행하고 발표 자료와 준비를 할 예정으로 보인다.

아침에 1시간씩 진행하는 CS는 Level1(캠프에서 문제 잔뜩 모아놓고 레벨 매겨줌)부터 시작해서 현재 Level3 문제들을 지나고 있는데, 슬슬 한 문제당 푸는 시간이 늘어나는 게 느껴진다. 아직 간단한 문제지만 문제당 이제 평균 10분을 넘어가는 듯 한 기분. 문제를 풀기보다 매번 내가 찾아보는 게 대체 무엇인지 메모해두는 게 좋을 것 같다. 오답노트 공부하듯이 나중에 CS부분만 몰아보면 좋을 듯. 유감이지만 오늘은 메모한 것이 없다.

 

2. 오늘 학습에 대해

콘솔 UI에 파티클 로직을 구현하였다. 모든 파티클이 랜덤으로 깜빡인다거나 하는 건 아니고, 주기적으로 파티클 문자 n개를 화면에 띄우고 지우고를 반복한다.

콘솔 화면에 파티클 이펙트를 보여주는 코드의 진행

string titleArt = "{아\n스\n키\n 아\n트}" // 콘솔에 출력할 내용
InitializeScreenBuffer(titleArt); // 콘솔에 출력하기 전, 내용을 저장
DrawAsciiArt(titleArt); // 콘솔에 WriteLine() 할 뿐인 메서드

// '+' 문자를 화면에 {num}개 만큼 생겼다 없어지는 파티클 이펙트.
// 너비 95, 높이 41의 범위에 800ms마다 갱신되도록 했다.
int width = 95; int height = 41; int num = 15; int msDelay = 800;
effectThread = new Thread(() => UpdateEffect(width, height, num, msDelay)); effectThread.Start();

// 키 입력을 받으면 스레드를 종료하여 다음 장면으로 넘어갈 준비를 한다.
Console.ReadKey();
keepRunning = false; // 스레드에 종료 신호를 보냄
effectThread.Join(); // 스레드가 종료될 때까지 대기

// 다음 장면으로 넘어감


(1) InitializeScreenBuffer
해당 메서드의 목적은 콘솔 화면에 표시할 내용을 '버퍼(buffer)'라는 메모리 구조에 저장하는 것

버퍼 : 데이터를 임시로 저장하는 메모리 공간

static void InitializeScreenBuffer(string s) // 내용을 버퍼에 저장하기
{
    int width = Console.WindowWidth;
    int height = Console.WindowHeight;
    screenBuffer = new char[height, width]; // screenBuffer는 함수 밖에 전역변수로 선언을 해두었다
    // 아스키 아트를 버퍼에 저장
    using (var reader = new StringReader(s))
    {
        string line;
        int y = 0;
        while ((line = reader.ReadLine()) != null)
        {
            for (int x = 0; x < line.Length; x++)
                screenBuffer[y, x] = line[x];
            y++;
        }
    }
}

Console.WindowWidth 와 Console.WindowHeight 를 사용하여 현재 콘솔 창의 너비와 높이를 불러온다.
콘솔 창의 너비와 높이에 해당하는 배열의 크기를 갖는 2차원 배열 screenBuffer 를 생성.
screenBuffer 는 버퍼의 역할을 하며, 콘솔 화면에 표시될 각 문자의 위치를 저장.
+ Height를 콘솔의 크기보다 높게 설정해야 하는 경우도 생길 수 있지만, 일단은 콘솔 높이를 사용.

StringReader를 사용하여 주어진 문자열 s 를 한 줄씩 읽는다.
각 줄을 순회하며 각 문자를 screenBuffer 배열에 저장.
y 변수는 현재 처리 중인 줄(행)의 번호. 
x 변수는 줄 내의 문자(열) 위치.

screenBuffer에는 asciiArt의 각 문자가 콘솔 화면상의 해당 위치에 매핑된다.
이후에 콘솔 화면에 어떤 변화가 필요할 때, 이 버퍼를 참조하여 어떤 문자가 원래 어느 위치에 있었는지 알 수 있다.

예시) "AB\nCD" 를 버퍼에 저장
screenBuffer[0, 0] = 'A'
screenBuffer[0, 1] = 'B'
screenBuffer[1, 0] = 'C'
screenBuffer[1, 1] = 'D'

(2) 이후 콘솔에 내용을 출력하고( DrawAsciiArt(titleArt) )

 

(3) 매개변수로 (1) 파티클이 나올 직사각형 범위, (2) 파티클 갯수, (3) 깜빡이는 주기 를 넘겨 일정 시간마다 랜덤한 위치에 파티클 효과가 보이도록 한다.

+ 지금 더 갱신된 코드는 파티클로 쓸 문자 char, 버퍼를 사용하지 않아도 작동하도록 하는 bool isBuffer 등을 추가하여 확장성을 높였다.

파티클이 지워지는 타이밍에, 버퍼에 저장되어 있던 내용을 기반으로 원래 문자를 복원한다.

 

(4) 마지막으로 키 입력을 받으면 스레드를 종료하도록 조건문을 넣어두었다.

 

콘솔 내 전각문자의 처리

위 내용의 구현 중 가장 큰 문제는 전각기호의 처리였는데, 반각문자인 파티클 '+'가 전각기호인 한글 문자 자리 등에 나타난다면, 한글문자가 이리밀리고 저리밀리고 해서 난장판이 되어버린다. 그래서 해당 위치가 원래 전각기호가 위치했는지 판별하는 동시에 전각기호의 왼쪽 혹은 오른쪽 중 어느 쪽에 '+'가 들어갔는지 판별하여 " +" 또는 "+ "와 같이 공백문자를 포함하여 해당 전각문자를 덮도록 설계하였다.

또한 전각기호를 복원할 때에도, 한칸 밀린 방향에 복원되지 않도록 조건 분기를 잘 나누어 제대로 된 위치에 다시 복원되도록 신경썼다.

위의 두 요소를 신경쓰니 전각문자가 이리저리 치이는 문제는 사라졌다.

아래는 문자가 전각문자인지 판별하는 코드이다

아마 모든 전각문자를 포함하고 있진 않을 것. 대표적인 범위만 설정.

static bool IsFullWidth(char c) // 전각문자인지 판별
{
    int[] ranges = { 
        0x1100, 0x115F, // 한글 자음과 모음
        0x2E80, 0x2EFF, // CJK(중국, 일본, 한국) 급진 부호
        0x3000, 0x303F, // CJK 심볼 및 구두점
        0x3200, 0x32FF, // CJK 호환성 음절
        0x3400, 0x4DBF, // CJK 통합 한자 확장
        0x4E00, 0x9FFF, // CJK 통합 한자
        0xAC00, 0xD7AF, // 한글 음절
        0xF900, 0xFAFF, // CJK 호환성 한자
        0xFE30, 0xFE4F, // CJK 호환성 형태
        0xFF01, 0xFFEF, // 하프와이드 및 풀와이드 형태
    };
    int code = (int)c;

    for (int i = 0; i < ranges.Length; i += 2)
    {
        if (code >= ranges[i] && code <= ranges[i + 1])
        {
            return true; // 전각
        }
    }
    return false; // 반각
}

전각문자 판별 메서드는 콘솔 한정 앞으로도 유용하게 써먹을 수 있을 것으로 보인다. 예를 들어 영어와 한글이 섞인 문자열끼리 폭을 같게 맞추도록 공백문자를 채워넣는 등 당장 생각나는 것도 몇 개 있다.

 

실행파일 생성

마지막으로 실행파일로 만들어서 다른 경로에서 직접 실행 해 보자고 갑자기 생각나서 해 본 내용.

크게 과정이 복잡하진 않았고, 

1. 빌드 세팅(1) - 프로젝트 속성

2. 빌드 세팅(2) - 대상 OS 버전 대충 win7 등 고름

3. 빌드 - Debug에서 Release로 바꿔준 후, 빌드

4. exe 파일 기본 생성 위치, 다른 곳으로 가져갈 때 파일 세개만 챙기면 잘 실행되는 것으로 보임

우리 조 슬랙에 설명용 쓰려고 대충 찍은 스크린샷이라 크기가 들쭉날쭉하다.

저렇게 생성된 파일 중, 체크표시한 유형 세가지만 챙겨가면, 다른 환경에서도 잘 실행 될 것으로 예상된다.

 

3. 과제에 대해

  • 내일부터 CS 중 검색하는 내용 생기면 무조건 적어두기
  • 발표 준비 돕기(본인 발표자가 아님)

 

4. 참고자료

반응형
COMMENT