게임 소개

24-1 윈도우 프로그래밍 최종 프로젝트 버전

 
2명의 플레이어는 협동하여 하나의 탱크를 조작한다.
탱크의 이동, 연료 보충, 공격, 장전은 누군가 자동으로 해주지 않는다.
서로 소통하고 협력하여 6개의 보스를 잡아라
 


들어가며

24년 초, 막 군대를 전역하고 뇌는 그대로 리셋되고 
잘쳐줘야 말하는 감자인 상태로 학교에 복학을 하면 
학교에서는 윈도우 프로그래밍 이란 걸 배우게 시킨다.
 
윈도우 프로그래밍에서는 최종 프로젝트로
C/C++ 기반의 Window API를 이용해서 2D 게임을 만들도록 한다.
기간은 4주.
정말 아무것도 모르는 상태에서 시작해서 시행착오도 많았고, 고생도 정말 많이 했지만
지나고보면 나름 재미있는 과목이었다.
 
각설하고 Brace for impact는 윈도우 프로그래밍의 기말고사겸 텀프로젝트였다.
인생 첫 프로젝트였기도 하고, 나름 애정이 많은 친구다.
 
 
 
 


 

기획

초기

군대를 가기 전 21년 겨울에 한 가지 게임을 기획해놨었다.
당시 재밌게 하던 게임 Overcooked에 영향을 받아
다 함께 소통하고 협력하며 스트레스 받는 그런 게임을 만들고 싶었다.

당시에 작성했던 기획서이다.

 
 
 
초기 기획은 플레이어가 4명이었고, 탱크가 아닌 2족 보행 로봇이었으며,
테마는 스팀펑크가 아니었다.
 

 
파워레인저 같은 4명의 플레이어가
로봇의 팔,다리, 머리, 무기 등을 마구마구
조작하며 적과 싸우는 그런 게임이었다.
 
흔히 말하는 메카 괴수 대전이었다
 
하지만 서버를 구현할 수 없었고, 하나의 컴퓨터로 작동해야 한다는 점에서
플레이어는 2명으로,
 
내가 2족 보행 로봇의 모든 애니메이션 스프라이트를
그리기엔 무리가 있어서 탱크로 교체했다.
 
스팀펑크로 교체한 이유는 나도 잘 모르겠다.
바꾸고 나서 진행해보니
스팀펑크는 디테일이 너무 많이 필요한 테마라서
진행하면서 내내 후회했었다.
 
 
그렇게 다시 작성한 게임의 프리뷰는 이런 느낌이었다.
(아무것도 모르고 작성한 기획서라 내용이 많이 미흡하다)
 
 

Brace for impact 초기 프리뷰

플레이어는 각자의 구역을 가지고 각자 역할이 공격과 이동으로 구분되어 있었으며,
간접적으로 서로를 도울 수 있었다.
한명은 탱크의 포신 부분을, 한명은 탱크의 차체 부분을 조종하는 게 재밌겠다 하는 생각이었다.
 
하지만 팀원의 의견을 반영해서 조종실을 하나로 합치고, 각자 맡은 일이 있다기 보다는
유동적으로 때에 따라 서로 할 일을 해야하는 게임으로 변경되었다.
 
 
 
 


개발

개발을 진행하기 전에, 한 가지를 정하고 시작했다.
우선, 우리 팀에 게임 개발 경력이 없다는 점,
그 이유로 밸런스나 기획 부분에서 문제가 있을 수 있기 때문에
작동 가능한 프로토타입을 먼저 만들기로 했다.
 
첫번째로 한 것은 네모로 된 플레이어를 추적하는 사각형들을 만드는 것이었다.
 
이후 프로젝트는 점차 진행되었는데,
아트로 코드를 단순화시킬 수 있음을 알았다.
 

 
예를 들어보자. 
이 탱크 이미지는 탱크 전체가 하나의 그림이 아니라
포신과 차체. 이렇게 2부분으로 나눠져 있다

 
 
자, 이제 플레이어의 입력에 따라서
차체는 총 상하좌우, 그리고 대각선까지 총 8방향
마찬가지로 포신도 상화좌우 대각선 총 8방향으로 돌아가도록 해야한다.
 
 
 
 

 
 
 
 
 
어떻게 할까?
 
 
프로그래머를 닦달하고 겁박하고 고문해서 위에 이미지를 8방향으로 회전시킬까?
좋은 생각이다.
 
하지만 이 게임은 쿼터뷰(Quater View)이다.
그리고 픽셀로 그려진 그림은 단순히 돌린다고 자연스럽게 보이지 않는다.
 
 
답은 간단하다. 그냥 다 그리면 된다.
 
이 방법은 용량은 늘어날지언정 (프로그래머의)개발 복잡도, 시간 복잡도를 아주 낮춰준다.
 

 
예를들어 탱크의 포신을 회전시킬 때는 코드를 통해 이미지를 회전시켜도 되지만,
 
처음부터 모든 프레임을 그려두면 굳이 그럴 이유가 없이
사진의 출력할 위치만 잡아주는 것만으로도 회전하는 탱크를 구현할 수 있다.
 
추가로, 중간중간에 프레임을 부드럽게 해주는 중간 프레임들을 그려넣으면
더 부드럽게 회전하는 포신이 완성된다.
 
 
몬스터도 마찬가지이다. 
 

 
 
적의 이동모션, 피격, 사망, 공격 등,
모든 경우의 수를 생각하고 그린다.
 
팀원 중 누군가 손을 계속 놀리고 힘든 시간을 보내고 있을 때
팀에 평화가 찾아온다
 
 
 
 
탱크 내부도 마찬가지이다.
내가 포를 쏠때마다 탱크가 뒤로 움직이게 하려고 한다.
 
코드를 통해 사진을 뒤로 뺐다가 몇 프레임 후, 다시 앞으로 옮겨도 된다.
하지만 모든 걸 그려넣는 게 시간도 훨씬 빠르고 다양한 문제들을 사전에 방지할 수 있도록 한다.
 

탱크 내부 포신 발사 애니메이션

 
 
 
아 그리고 한가지 더,
스프라이트를 그릴 때는 반드시 이미지 내에 이 전체 이미지의 가로 세로 길이가 어떻게 되는지와
어디서부터 어디를 사용할건지를 적어두자.
 
그 까닭은 개발 시 이 스프라이트의 크기를 확인하는 데 꽤나 많은 시간이 들기 때문이다.
 
디자이너가 사진의 전체 크기와 한 칸의 크기를 명시해주지 않으면
꽤나 많은 혼선과 불화가 생긴다.
사진에 직접 수치를 써넣지 않더라도 문서를 통해 알려줬다.
 
사실 이미지 그리고 코드에 적용하는 건 내가 맡아서 한 부분이라 불화가 생길 일은 없었지만...
그래도 내 머리가 모든 것을 기억하지는 못하기 때문에 적어두는 것이 편하다 아무튼
 
 
 
 


충돌처리

개발 초창기 맵이다.
 
위에 큰 도로에서 탱크가 출발할 예정이고, 탱크는 벽이나 건물을 가로질러서 갈 수 없다.
그러기 위해서는 "여기는 지나갈 수 없어"라는 충돌처리를 해줘야한다.
 
아쉬운 점은 우리가 이때 충돌처리를 어떻게 해야할 지 잘 몰랐던 점이다.
 
생각했던 건 맵 곳곳에 보이지 않는 사각형을 들어갈 수 없는 부분마다 배치해둬서
장애물 네모와 탱크 네모의 충돌 시 이동하지 않게 하자는 것이었다.
 

 
그래서 이런 식으로 맵에 어떤 위치에 사각형을 배치하면 되는지를 작성해줬다.
만약 세세한 수정이 필요할 때는 아래에 수정 사항들을 적어뒀다
 
 

 
말로 설명하기 어려운 컷씬이나 연출의 경우
파워포인트 애니메이션을 제작해서 보여줬다
 
 

 
몹의 정보와 몹의 패턴 역시 이런 식으로 작성해서 팀원들에게 전달했다.
 
하면서 들었던 생각은 이걸 도식화해서 보여줘도 괜찮았겠다 였지만
후에 Deutornomy 때 도식화해서 보여준 걸 한번도 안읽어봤다는 걸 깨달은 후
그냥 글과 그림으로 적어서 보여주는 게 제일 좋구나를 느꼈다.
 
아니면 내가 못그려서 그런가?? 잘 모르겠다
 

적 투사체, 탱크 미사일, 자원
적 등장 컷씬

 
아무튼 정말 별의 별 것들을 다 그려서 넣었다.
 
 
 
 
 
 
 

최적화

 

이 게임에서는 전체 맵 중 탱크가 있는 곳을 기준으로 카메라를 잡아준다.
그 뜻을 카메라 밖에 있는 요소들을 그려두고 있을 필요는 없다는 의미다.
 
그래서 적이나 탄막이 카메라 밖으로 벗어날 시
그리지 않도록 구현해뒀다.
이 과정으로 한 20프레임정도 더 성능 개선을 할 수 있었다.
 
 

 
이미지의 경우 따로 헤더(.h)를 만들어서 이런 식으로 관리했다.
게임 초기 시작 시 모든 이미지를 로드하고,
필요할 때만 출력하는 방식으로 최적화를 했다.
 
 
 
 


 

공모전 Ver.

성공적으로 프로젝트를 끝마치고,
할거 뭐 없나 찾아보다가
만들래 라는 사이트에서 10분 게임 콘테스트라는 걸 봤다.
 
우리 프로젝트는 시연용으로는 문제가 없었다.
어차피 우리가 만든 게임 우리가 플레이하니 룰이며 공략이며 전부 알고 있다.
 
 
 
하지만 아무것도 모르는 사람들은
이 게임이 어떻게 해야하는 것인지, 뭐가 목표인지를 모른다.
 
그래서 게임 룰을 더 자세하게 작성하고, 편의성 등을 개선했다.
 
제일 먼저 한 것은 룰북을 이해가 되도록 새롭게 그려넣은 것,

시연 버전 룰북
공모전 버전 룰북


한 페이지짜리 룰북을 4페이지짜리로 바꿔서 넣었다.
글을 작성하지 않고 이미지로만 설명하려다보니 잘 설명이 됬는지는 모르겠다
 
그리고 시연 때는 저작권에 상관없이 아무 노래나 가져다가 썻엇는데,
공모전에서는 문제가 될 것 같아 저작권 문제가 없는 노래들로 바꿨다.
 
 

 
결과는?
 
한 반타작 정도 했다.
그래픽 개선이 되기 전에 평가를 받아서 그래픽 감점이 있었다.
 
사실 너무 좋고 재밌는 게임이 많아서 큰 기대는 안했다.
 
하지만 다수가 내 게임을 플레이하도록 내놓아보는 건 꽤나 큰 경험이었다.
어떻게 해야 사람들이 진행 방식을 손쉽게 이해하고,
어디서 어떤 평가를 내놓는지를 확인할 수 있었다.
 
 
 
 
 


과제전 Ver.

 

 


 
 

 
 
 
10월쯤에 학교에서는 한국공학대전이라는 큰 대회가 하나 열린다.
보통은 우수한 성적을 받은 졸업작품들을 전시하는 행사인데,
우리 게임공학과에서는 졸업생이 아닌 재학생들을 위해 작게나마 과제전이라는 걸 개최한다.
 
 
우리 과는 거의 매 학기마다 게임을 만드는 과제를 낸다.
그 중에서 본인이 좀 잘했다 싶은 사람들을 대상으로 본인의 과제를 체험할 수 있게 하는 행사이다.
 
만들어둔 게 아까운 관계로 과제전에도 참가를 했었다.
 
가장 우선했던 것은 그래픽의 개선이었다.
대충 GPT 돌려서 빠르게 그래픽을 만들어야 했던 그때와 달리,
지금은 시간도 (비교적) 넉넉했기에 다양한 레퍼런스들을 참조하며 그래픽을 개선했다
 

맵 디자인 수정

초기 개발 때는 맵 종류 단순히 3가지였다.
보스는 총 6마리이므로 한 맵을 2번씩 사용했다.
과제전을 준비할 때는 맵을 새롭게 다시 그리면서
낮과 밤 이렇게 바꿔 모든 보스가 자신만의 맵을 가질 수 있도록 바꿨다.
 
자세히 보면 기존 맵에서 전체적인 틀 자체는 비슷한 걸 볼 수 있다.
맵을 바꾸면서 힘들게 만들어두었던 충돌 처리 장애물들의 위치를 바꾸기 싫었기 때문이다...
 
 
 

조작기 변경

 
조작지 디자인도 많이 바꿨다.
기존 이미지는 시간이 너무 없어서 그냥 어디서 가져오거나
GPT가 그려준 그림인 반면
다시 그릴 때는 조금 더 탱크 내부에 알맞도록 노력해봤다.
 
 

 
탱크 내부 이미지도 변화를 주었다.
개발을 하면서 가장 우려됬던 부분은
시연해보는 사람들이 과연 룰북을 열어볼까? 였고
설령 룰북을 보더라도 그 조작들을 모두 외울 수 있을까? 였다.
 
그래서 그냥 탱크 내부에 조작키를 그려넣었고
어떤 게 어떤 기능을 하는지 최대한 가시성있게 그려넣으려고 했다.
 
 
 

그리고 조작기에 상호작용이 가능한 범위에 들어오면
F나 M을 눌러서 상호작용해보라고
다음과 같은 아이콘도 만들었다.

이런 식으로 상호작용 가능한 범위 내에서 
어떤 키를 눌러야하는지를 시각적으로 보여줬다
 

텀프버전 최종 보스

 
컨텐츠면에서도 변화가 있었다.
기존 최종 보스는 패턴이 단 한가지였으며
마지막 보스라기엔, 그다지 이펙트가 있지 않았다.
 
 

과제전 버전 최종보스

 
 
 
그래서 
새롭게 보스를 그렸고,
이 최종 보스는 3가지 패턴을 가지도록 만들었다.
 
 
 
사운드에서도 변화가 있었다.
기존에는 WindowAPI에서 지원하는 Playsound()함수를 사용했었다.
Playsound는 사용이 간단하지만, 매우 치명적인 문제가 있는데,
한번에 단 한가지 음악만 재생할 수 있다는 것이다.
 
이말은 BGM과 사운드이펙트를 동시에 재생할 수 없다는 의미이다.
 
그래서 이번에는 FMOD 라이브러리를 직접 적용했다.
 
이제 한번에 여러 소리를 출력하게 할 수 있게 되었다.
탱크 이동 소리, 피격 소리, 적 공격 소리 등등...
 
그리고 탱크와 적의 거리를 계산해서 적이 멀수록 적이 내는 사운드가 더 작게,
가까울수록 사운드가 크게 들리도록 했다.
 
이제 플레이어는 소리를 통해 적의 위치를 가늠할 수 있다.
 
 
또 이제는 벨런스 조절이 중요했는데,
한 보스를 테스트하겠다고 처음부터 게임을 모두 하기는 시간이 너무 오래 걸린다.
 
그래서 디버그 모드를 따로 제작해서 스테이지를 선택하거나
무적으로 만드는 등을 통해 쉽게 밸런스를 조절할 수 있었다.
 
과제전 전날까지 열심히 달렸다.
 
그리고 과제전 당일,
 

쌈뽕하게 포스터도 만들었다.
 
 

 
옆에는 듀얼모니터를 연결해서 플레이하기 쉽도록 간단한 튜토리얼 영상을 띄워뒀다
이 게임을 어떻게 해야하는 지 몰라 재미가 반감되는 일은 없어야 했다.
 
나는 이때 진심이었다.
 
전날에 과제전 진행 전 마지막 버그 수정 및 컨텐츠 추가하느라 딱 3시간자고 바로 다시 나왔다.
진짜 오는 사람들 응대하고 어떻게 해야하는 지 알려주느라 오전 10시부터 오후 6시까지 쉬지도 못했다.
몸은 정말 힘들었는데, 버틸만했다.
 
내가 만든 걸 누군가한테 보여준다니
정말 흥분되는 일이 아닐 수 없다.
 
 
 
별개로, 결과는 어떻게 될 지 알 수 없었다.
같은 윈도우 프로그래밍 분야 참가자들의 퀄리티도 좋았고,
어떻게 했는지도 모르겠는 기술들을 구현한 팀도 많았기 때문이다.
 
팀원들 생각도 똑같았다.
2등은 받을 수 있으려나...
하고 있었는데
 

 
헉 최우수상이었다
진짜 이때는 예상도 못했다.
 
그래 그래도 고생했다 이런 생각으로 맘 편히 기다리고 있었는데,
정말 고맙게도 최우수상을 받았다.
 
상금으로는 15만원과 마우스 패드를 받았다.
근데 3명이라서 5만원씩 나눠가졌다.
 


후기

 
 

'프로젝트' 카테고리의 다른 글

『Deuteronomy』 개발 후기  (0) 2025.01.24

 

 

 

목차

    Deuteronomy

    게임 소개

     

     

     

    폐성당에 들어가게 된 주인공이 무사히 탈출하는 것을 목표로 한다.

    괴물은 플레이어를 눈으로 인식할 수 없고, 맵 곳곳에 배치된 카메라(눈)에서 발광하는 빛으로 플레이어를 감지한다.

    이 카메라는 계속해서 다른 카메라로 시야를 이동하며, 플레이어도 이 카메라로 현재 적의 위치를 확인할 수 있다.

     

    뭐 그런 게임이다.

    아웃라스트(Outlast)몬스트럼(Monstrum), 사혼곡:사이렌을 주로 참고했다.

     

     

     


    들어가며

     

    24년 2학기 때 OpenGL 최종 텀프로젝트 과제로 공포 게임을 개발했었다.

    개발 기간은 3~4주정도인데 중간에 시험 준비와 다른 텀프로젝트 준비와 겹쳐서 정말 빠듯했다.

     

    프로젝트 후기에 앞서서 OpenGL이 어떤 것인지에 대해 설명이 필요할 것 같다.

    현재 재학 중인 학교 한국공학대학교의 2학년에는 복학생들을 절단하기로 유명한 2개의 과목이 있다.

    하나는 2학년 1학기 때 진행하는 "윈도우 프로그래밍", 하나는 2학년 2학기 때 진행하는 "컴퓨터 그래픽스"이다

     

    군대에서 리셋된 머리를 다시 굴리려고 하면 정말정말 까다롭고 숨이 턱 막히는 과목들이었다.

    C/C++도 모르는 상태에서 윈도우 프로그래밍을 실습할 때, 정말 하나도 모르겠어서 너무 우울했고 힘들었다.

     

    각설하고, 2학기 때 수강해야하는 "컴퓨터 그래픽스" 3차원에 대해 자세히 다룬다.

    OpenGL이라는 그래픽 라이브러리를 이용하는데, 윈도우 프로그래밍을 수강하며 겪은 그 충격을 생각하며

    방학 때 미리 조금 준비했음에도 정말 까다로웠다.

    3차원부터는 벡터와 행렬과 같은 수학이 응용되기 때문이다.

    심지어 엔진도 아닌지라 모든 것, 진짜 모든 것을 내가 전부 작성해줘야 한다.

    예를들자면, 충돌처리, 카메라 배치, 애니메이션, 맵핑 등 엔진에서는 딸깍이 가능한 모든 것들을 수동으로 해줘야 한다.

    그래서 많은 어려움이 있고, 기획 단계에서도 개발이 가능하도록 많은 신경을 써서 진행했어야 했다.

     

     

     


    기획

    초기 기획을 정하는 데에 큰 어려움이 있었다.

    내 팀원이 애니메이션이 있는 게임을 원했기 때문이다.

     

    OpenGL에서 애니메이션을 구현할 수 있다면 좋지만, 이전 선배들의 작품들을 참고했을 때

    애니메이션을 구현한 사례는 눈에 띄게 적었고 대체로 간단하되 참신한 게임들이 많이 보였다.

    교수님께 여쭤보아도 애니메이션이 큰 가점 요소는 되지 않고, 비용이 많이 들기 때문에 간단한 조작의 게임을 추천하셨다.

     

    그래서 초기 기획은 2.5D 픽셀 스타일의 간단한 게임 혹은 캐쥬얼한 느낌의 게임을 원했다.

     

    Soyaa - 2D Character Sprite Exploration Gameplay in 3D environment

     

     

    당시에 막 윈도우 프로그래밍 과제전(Brace for Impact)을 끝냈던 참이었고, 픽셀 애니메이션을 더 해보고 싶었다.

    그리고 3D 모델의 애니메이션과 다르게 2D 픽셀 애니메이션은 구현이 비교적 쉽고

    *빌보드만 적용되면 가능했기에 더욱 매력적인 요소였다.

     

    (빌보드(Billboard): 카메라의 현재 시점에 대해 2D이미지가 평면처럼 보이도록 회전)

     

     

     

    그게 아니라면 이런 캐쥬얼한 느낌의 3D 게임을 만드려고 했다.

     

    하지만 같이 프로젝트를 진행하게 될 팀원이 3D 애니메이션을 원했다.

    너무나 단호했다. 한 9개 정도의 기획안이 빠꾸 당했다.

    그리고 같이 스터디하는 다른 인원들이 모두 애니메이션을 구현하려하고 있었다.

    그래서 하기로 했다(지금 생각해보면 정말 잘했다.)

     

    또 보니까 이 친구가 프레임워크와 조명, 카메라가 기본 구현되는 코드를 먼저 작성해왔다.

    그래서 애니메이션이 작용하는 기획안을 작성했다.

     

     

    이걸 작성할 때만 해도 이미 그 전에 너무나 많은 기획안이 빠꾸당해서

    뭘 좋아할지 몰라 다 준비해봤어 느낌으로 그냥 마구마구 찍어냈다.

    대부분은 컨셉만 있으며 구두로 설명이 진행됬다.

     

    이 중에서

    1. 애니메이션 작동을 내가 잘 확인할 수 있는가?

    2. 조명과 카메라를 잘 활용할 수 있는가?

    3. 어둡고 공포스러운 느낌이면 좋겠다

    4. 신축과 이동, 회전이 잘 적용되는가?

    5. 개발을 시간내에 끝낼 수 있을정도의 분량인가?

     

    이 5가지 요소에 집중해서 선택한 것은

     

     

    여기 보이는 이거였다.

     

    애니메이션을 잘 확인할 수 있게 괴물의 시야로 내가 보여야 했고,

    조명과 카메라를 활용하기 위해 조명에 접촉 시 괴물이 추적을 하게 했고

    어둡고 공포스러운 느낌을 위해 조명과 엠비언트 값을 최소화했으며,

    다양한 오브젝트신축, 이동, 회전을 적용했고

    단순한 술래잡기같은 기믹으로 분량을 최소화했다.

     

    이제 기획은 완료됬고, 가장 우선 애니메이션을 구현해야 했다.

     

     


     

    개발

    애니메이션

    Clrain_Dev - OpenGL Graphics Pipeline Programming : [2023-2 컴퓨터 그래픽스 기말 프로젝트] 애애니

     

     

    애니메이션을 구현한 사례가 있는지 사전조사를 진행했다.

    이름도 얼굴도 모를 어떤 선배의 애니메이션 결과물을 발견했다.

    대단했다. OpenGL로 이정도도 가능하구나를 느꼈다.

    엔진도 아닌 환경에서 애니메이션 구현과 보간 등을 모두 구현해낸 것이다.

    이정도만 되어도 한이 없겠다라는 생각에서 구현을 시작했다.

     

    감사하게도 이후 프로젝트 제출 영상에 댓글을 달아주셨다. 호들갑 떨까하다가 말았다.

     

     

     애니메이션 구현의 첫 단계는 메인 프로그래머 팀원이 블렌더에서 제작된 애니메이션 정보를 읽을 수 있도록

    프레임워크를 수정한 후 이루워졌다.

    뚱이

     

     

    우리의 첫 목표는 이렇게 생긴 뚱이 친구의 애니메이션을 구현하는 것이었다.

    모델링은 자체 제작했지만, 애니메이션 본 작업은 https://www.mixamo.com/  (일명 믹사모)에서 딸깍으로 진행했다.

    내가 아직 애니메이션에 본을 작업하는 걸 잘 몰랐기 때문이고, 이게 편했기 때문이다, 믹사모 짱짱

     

    정상적으로 잘 작동한다면 이 친구는 왼쪽 오른쪽으로 카포에라를 진행해야 한다.

    카포에라

     

     

    이런식으로 동작해야 한다

    (저 모델링이 움직이는 걸 가져오면 좋은데, 파일 정리를 하면서 사라졌다. 블로그에 글 쓸줄도 몰랐고)

     

     

    결과는?

     

     

    카포에라는 아니지만, 같은 오류이다... 이전 영상을 지웠버려서 대체한다

     

     

    움직이기는 하는데 자꾸 팔다리가 마구마구 늘어나서 호전적인 자세를 취한다!

    그 이유를 알 수 없었다. 우리 팀보다 먼저 애니메이션을 작업하던 팀에서도 계속해서 발생하는 문제였다.

    그렇지만 이게 게임의 핵심이었기 때문에 이 문제를 반드시 해결해야만 했다. 

     

     

    무한 우끼끽 이론

     

     

     

    무한 원숭이 이론을 아는가?

    무한한 수의 원숭이와 무한한 수의 자판기가 있다고 가정한다.

    만약 원숭이들이 모든 자판을 랜덤하게 입력한다고 하고,

    무한한 시간이 존재한다면 셰익스피어의 희곡 전편을

    언젠가는 작성할 수 있지 않을까? 하는 이론이다.

    (불가능하다고 판정났다)

     

    결과가 어떻든,

    나는 이 포기를 모르는 원숭이들이 존경스러웠다.

    이 문제를 해결하기 위해서 이들을 본받기로 했다.

     

    나는 원숭이도 아니다 (팀원 생각은 다른 것 같다)

    모든 입력을 랜덤하게 하지도 않는다 (팀원 생각은 다른 것 같다)

    시간도 많다 (팀원 생각은 다른 것 같다)

    그러니 이론상 이 문제를 유한시간 내에 끝낼 수 있다!

    킵고잉~

     

     

     

    될 때까지 블렌더에서 파일 추출할 때 있는 모든 기능들을 꺼보고 켜보고를 반복했다.

    이 방법은 "코드에 문제가 없다면 분명히 모델링에 문제가 있을 것이다" 라는 점에서 시작한다.

    (추후 팀원은 이를 발전시켜 문제해결 파이프라인 4단계의 이론을 정립했다)

    그렇게 파일 이름도 DDung(1~9) -> D(1~9) -> RealDDung(1~9) -> Man(1~9) -> RealMan까지 갈 때쯤,

    RealMan4의 시도에서 드디어 성공했다!

    우끼긱

     

     

    RealMan4의 성공

     

     

    마침내! 뚱이가 카포에라를 시작했다!! 호전성도 전혀 보이지 않았다!!

    이때 나는 전날 밤샘에 씻지도 못하고 있다가 샤워하러 잠깐 자취방에 들어갔을 때 였다.

    팀원이 나를 급하게 찾아서 카톡을 보고 잠깐 해봤는데, 성공했다.

    도파민 풀로 차서 견딜 수가 없었다.

    그 자리에서 물기도 안 닦고  팬티만 입은 채로 다른 시도를 계속했었다.

     

    성공의 순간

     

     

    이후 테스트를 하며 몇가지 문제들도 있었지만, 결론은 이거였다.

    OpenGL 환경에서 애니메이션 정보를 3D Max, Blender와 같은 모델링 툴을 통해 불러오고 싶다면

    FBX파일 포맷이 아닌, GLB/GLTF를 사용해야 한다!

    이름부터 GL이 들어가 있는데 이 생각을 못했었다.

     

    FBX는 뼈 정보와 가중치를 통해 애니메이션을 인식하지만, GLB/GLTF는 관절을 설정하고 회전시키는 방식이다!

    맞지도 않는 걸 먹이려고 드니 애가 그렇게 호전전성을 보이지.

    그렇게 애니메이션을 구현했다.

     

     

     


    조명과 카메라

    애니메이션은 가장 큰 문제였지만, 다른 문제들도 여전히 있었다.

    그 다른 문제는 조명과 카메라였다.

    (이 밖에도 Blender와 OpenGL의 좌표축이 다르다는 점이 있었지만 뭐, 이거는 직접 돌려보면 되서 큰 문제는 아니었다)

     

    처음에는 Blender에서 스테이지를 제작한 후 조명까지 설치해서 Export하려 했으나

    (Assimp에서 GLB내의 조명을 읽을 수 있는 코드를 구현했다)

    아쉽게도 좌표축이 뒤틀리는 문제가 발생했다.

    그래서 그냥 인 게임내에서 조명의 위치좌표와 바라보는 Direct 및 밝기 값 등을 직접 하나하나 수정해줬다.

     

    카메라도 큰 문제는 아니었다.

    매번 교수님이 폭탄처럼 던지시는 과제 중에는 *뷰포트(Viewport)를 여러개 만들어

    다양한 시점으로 사물을 보게 하는 과제가 있어서, 이를 응용해서 만들었다.

    *뷰포트(Viewport): 윈도우가 사상되는 출력 장치의 영역, 즉 사용자에게 보여지는 구간

    뷰표트 분할

     

     

    이런 식으로 카메라를 2개로 나눠서 볼 수 있다. 

    원래는 1:1 비율로 화면이 분할되면 좋겠다였으나

    막상 적용해보면 화면이 위쪽으로 쭉쭉 늘어나버리게 된다

     

     

     

     

     

     

    예를 들어 이런 그림을 절반으로 줄이고 다른 쪽에 절반으로 줄인 다른 그림을 넣는다면

     

     

     

    이런 식으로 2개의 그림 모두 위아래로 늘어나 버린다. 

    그래서 생각한 방법이 "비율을 2:3으로 바꾸고 한 쪽면을 칠해서 늘어남이 잘 보이지 않게 하자" 였다.

    그림 실력이 부족해 저렇게 나오고 말았지만, 나름 괜찮았던 것 같다.

     

     

     


    A*(에이스타)

    A*는 다익스트라에 기반하는 길찾기 알고리즘이다.

    다익스트라 알고리즘은 현재 위치로부터 가장 가까운 목적지를 찾아내는 알고리즘으로

    그냥 가장 최적의 거리를 계산해서 이동한다고 생각하면 된다.

     

    원래 이전 프로젝트였던 Brace For Impact에 구현해보려고 했으나

    차마 엄두도 내지 못하고, "단순 추적 + 벽에 부딪히면 벽타고 이동"으로 적의 추적을 구현했는데,

    똑똑이 팀원이 A*를 구현해왔다.

    A*가 구현 여부에 따라 맵에 더 많은 장애물을 배치하고, 복잡한 구조를 제작할 수 있었기에

    이는 굉장히 의미있는 기술이자, 내가 할 일이 많아짐을 의미했다.

     

     

     

     

     

     

    (레벨디자인을 어떻게 하는지도 잘 몰라서 추잡하게 그려놓았다!)

    A*가 적용되기 이전에는 단순히 하나의 큰 홀에서 진행하는 것을 의도했다.

    방에 들어가면 추적을 종료하고, 뭐 추적해도 벽 뚫는걸로 하자~ 였으나

    내 팀원은 A*개발과 동시에 복잡하고 구체적인 맵 디자인을 요구했다.

     

    그래서 새로했어야 했다.

    수정된 맵(블렌더로는 맵 만드는 거 아니다)

     

     

     

    그렇게 해서 완성된 맵은 이거다.

    A*가 정확하게 작동하려면 정수배(그중에서도 3m)로 한개의 타일을 배치했어야 했기 때문에

    모든 맵은 3m로 딱딱 나눠 떨어지도록 제작했다.

    그리고 어느 지점이 내가 지나갈 수 있는 곳이고, 아닌지를 작성해줘야 했다.

    누가? 내가

    40 * 40 크기의 A* 지도

     

     

    그렇게해서 작성한 것이 이 A* 지도이다. 블렌더를 뒤집어 까서 하나하나 일일이 작성했다.

    분명 더 쉬운 방법이 있었을 것이다.

    하지만 개발복잡도, 시간복잡도를 최소화하려면 내가 굴러야 했다.

    수제로 찍어가면서 몇가지 특징들을 더 추가할 수 있었는데,

     

    예를 들어 저기 보이는 

    0은 플레이어와 적 모두 통과가 가능한 구역

    1은 플레이어와 적 모두가 통과 불가능한 구역(벽)

    2는 플레이어와 적 모두가 통과 불가능한 구역(장애물)

    3는 플레이어는 통과가능하고 적은 통과하지 못하는 구역

    (몬스터의 덩치 때문에 벽에 겹쳐서 움직이는 것을 방지하기 위함이다)

    4는 특정 조건에서만 플레이어가 통과 가능한 구역이다(문)

     

    즉, 괴물은 0에서만 이동할 수 있게 해놓고, 나머지 구간들은 전부 예외로 처리해서 맵을 디자인했다. 

     

    그리고 팀원이 A*를 만들어 가져왔을 때, 

    어떤 위치를 지정하면 단순히 그쪽으로만 이동하는 정적 A*를 먼저 개발하고

    후에 실시간으로 좌표를 갱신해서 목적지로 이동하는 동적 A*를 후에 개발했는데,

    동적 A*만 사용하기에는 아까워서 정적 A*를 적의 행동 패턴에 적절히 잘 활용했다.

    적이 조명 위치로 뛰어가는 것은 이때 정적 A*를 활용하기 위해 새로 기획되었다.

     

     


    적(괴물)

    소개

     

    괴물씨

     

     

    플레이어를 추적하게 될 괴물이다.

    처음에는 이런 모습으로 만들 생각이 아니었다.

     

     

     

     

     

     

    이런 길쭉길쭉하고 기괴하게 생긴 괴물을 넣으려고 했다.

    이유는 내가 길쭉길쭉한데 빠른 것들을 무서워한다.

    나름 직접 모델링도 하고 이것저것 덧붙여서 애정 좀 들었는데, 사용되지는 않았다.

    스테이지를 다시 제작하는 과정에서 전체적으로 퀄리티가 조금씩 높아졌고,

    너무 *로우폴리곤인 캐릭터가 어울리지 않았다. 

     

    *로우 폴리곤(Low-Polygon): 적은 해상도의 3D모델, 크기가 작고 읽기 쉽다.

     

    그래서 그냥 sketchfab에 있는 캐릭터를 불러와서 약간의 수정 후 적용했다.

    https://sketchfab.com/3d-models/the-brute-a7e340fc3682453f8d0047f42df51044

    완성하고 느낀거지만, 이 덩치 괴물은 귀신이나 공포스럽기 보다는 너무 몬스터 같은 느낌이 들어서 별로였다.

     

     


    행동 패턴

    괴물의 행동패턴

     

     

    괴물은 다음과 같은 행동패턴으로 작동한다.

    물론 이 그림에는 어떤 조건에 어떤 상태로 바뀌는지가 자세히 적혀있지는 않다.

    처음에는 *유한 상태 기계를 직접 구현해서 해보려고 했으나,

    (유한 상태 기계(Finite State Machine): 캐릭터의 상태와 동작을 모델링하는 수학 모델. 일종의 순서도이다.)

    캐릭터의 상태가 게임 전체 진행에 큰 변화를 줘서 + 내가 잘 구현을 못해서

    이런 식으로 상태 패턴을 구현했다.

     

    꽤나 유용한 방법이었던 것 같다. 보기도 쉽고 사운드나 다른 조건들을 덧붙이기도 용이했다.

    다음 프로젝트에는 정확하고 구체적인 유한 상태 기계를 설계해보려고 한다.

     

     

     

     


    그밖에도

    다양한 기술들을 대거 구현했다. 내가 아니라 내 팀원이.

     

    부드러운 곡선 이동을 위한 쿼터니언 스플라인 보간,

    애니메이션 간의 자연스러운 보간, 

    쉐도우 맵핑,

    충돌 구현(AABB), 

    상태에 따른 4개의 쉐이더

    적이 얼마나 가까운 지에 따라 소리의 크기가 달라지는 기술 등을 구현했다.

     

    자세한 기술 설명은 나중에 한번에 해보도록 하겠다.

     

     

     


    후기

    이 프로젝트를 하겠다고 많은 것들을 포기했어야 했다. 

    중간에 과제도 많이 못했고, 시험 준비도 대부분 전날 아니면 2일전부터 시작했다.

    프로젝트 마감일 쯤에는 밤 새면서 강의실에서 자는 게 일상이었고,

    강의실 추운데 히터도 안틀어줘서 드라이기를 가져와서 몸을 녹였다.

    정말 쉽지 않았지만, 그럴만한 가치가 있었다.

    게임 개발은 재밌고, 흥미로운 선택의 연속이다.

     

    그리고 기왕이면 자료들을 많이 남겨둘 걸 그랬다.

    이렇게 작성하게 될 줄 몰라서 있는 자료들을 죄다 끌어와도 이정도가 끝이었다.

    그리고 글도 좀 두서있게 쓰도록 노력해야겠다.

    내가 써도 뭘 말하고 싶은지 모르겠네

     

     

     

     

     

     

     

    '프로젝트' 카테고리의 다른 글

    『Brace For Impact』 개발 후기  (0) 2025.02.23

    + Recent posts