본문 바로가기
C# 콘솔 & 윈도우폼

[C#] 콘솔로 슈팅게임 구현하기 3 : 갤러그

by 17번 일개미 2022. 7. 2.
728x90

 

개선점

 

2편에서는 10프레임 단위로 화면을 갱신하며 1편에 비해 매우 정상적인 플레이가 가능하였다.

하지만, 높은 프레임으로 올라갈수록 콘솔을 지우고 쓰는 속도가 빨라져,

화면 깜빡임이 매우 심해졌다. 따라서 이를 해결함과 동시에, 총알이 세 갈래로 나아가는 것도 구현했다.

또한 메인화면, 게임 종료 시 화면도 구현하였다.


전체 코드

는 생략. 코드를 다양한 스크립트로 분할하면서 여러 스크립트가 되었기에 전체코드는 생략한다.

크게 변경된 부분 코드만 적어보겠다.

 

로비구현

 

MainGame.cs

const int waitTick = 1000 / 60; // 60 프레임(60FPS)
        static void Main(string[] args)
        {
            int lastTick = 0; // 마지막 틱
            int currentTick; // 현재 틱
            Init.InitLobby();
            while(true)
            {
                if(Init.Start() == true)
                {
                    break;
                }
            }
            Init.InitWindow(); // 윈도우 창 초기화
            while (true)// 반복
            {
                currentTick = System.Environment.TickCount; // 현재 시간
                if (currentTick - lastTick < waitTick) continue; // 경과 시간이 1 / 60 초 보다 작다면 실행 건너뜀
                else // 조건 만족 시
                {
                    lastTick = currentTick;
                    if (ScoreLife.lifeCount == 0) // 목숨이 0 이면
                    {
                        KeyInput.ClearBuffer();
                        Init.EndGame(); // 종료 화면
                        continue;
                    }
                    KeyInput.CheckKey();// 키 입력 확인
                    Frame.DrawFrame(Frame.isAttack); // 프레임 렌더링
                    Bullet.CheckBullet(); // 총알 충돌 체크
                }
            }
        }

메인 스크립트에서는 로비에 진입하고 조건에 맞는 키를 입력받아 

게임을 실행하고, 목숨이 0 이되면 종료화면으로 넘어간다.

이 때, 게임 내내 누르고 있던 Space bar가 키보드 버퍼에 쌓여있는데, 이 버퍼를 처리하느라 종료화면에서

키 입력으로 인식되는 현상이 발생했다.

 

키보드 버퍼를 비우는 방법으로 아래의 방법을 사용했다.

 

KeyInput.cs

        public static void ClearBuffer()
        {
            while (Console.KeyAvailable)
            {
                Console.ReadKey(false);
            }
        }

해당 코드로 버퍼가 무시되었다. 이를 통해 종료화면 오류를 해결했다.

 

3발의 총알

Frame.cs

if ((i == bulletPos_L[0] && j == bulletPos_L[1] && isAttack == true) ||
                        (i == bulletPos_R[0] && j == bulletPos_R[1] && isAttack == true) ||
                        (i == bulletPos[0] && j == bulletPos[1] && isAttack == true))// 총알 위치라면
                    {
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.Write(pixel[i, j]);
                        Console.ResetColor();
                        Console.BackgroundColor = ConsoleColor.DarkCyan;
                    }

 

총알은 bulletPos, L , R  총 3개로 나누어 각각 발사했다. 

 

Bullet.cs

public static void MoveBullet()
        {
            if (isAttack == true)
            {
                bulletPos_L[0] -= 5; // 플레이어 총알 이동
                bulletPos_L[1] -= 1;
                bulletPos_R[0] -= 5;
                bulletPos_R[1] += 1;
                bulletPos[0] -= 5;
            }
            else
            {
                InitBullet();
            }
        }

각 총알의 이동은 중앙 총알은 일정 값만큼 전진하고

좌, 우 총알은 수평, 수직으로 방향에 맞게 1씩 추가로 움직여주면 전체적으로 대각선의 방향을 갖게 된다.

 

60 프레임

 

프레임 문제 해결은 간단했다.

Frame.cs

Console.SetCursorPosition(0, 0);

콘솔을 굳이 Console.Clear() 로 지울 필요없이, 커서의 위치를 0, 0 으로 초기화하고 덧씌우면 됐다.

 

 

추가적으로, 2편에 이어 플레이어의 모습이 더 비행기 답도록 변경해보았고,

적의 움직임은 한쪽 벽에 쏠리게 되면 무조건 방향 전환을 한 번은 하도록 해주었다.

728x90