2. 프로젝트 구조

  1. 헤더
  2. 엔진
  3. 관리자
  4. 레벨
  5. 오브젝트
  6. 컴포넌트



1. 헤더

자주 사용되는 구문을 define 매크로로 작성하여 모아두거나, 함수, 구조체, 열거형 등을 별도로 정의해 두고 헤더로 include 하여 사용한다.

각각 define.h, enum.h, function.h, struct.h, … 등으로 헤더 파일 별로 분류하여 작성하고, 이를 global.h 에 헤더를 include 하여 모아둔다.

이후 미리 컴파일된 헤더에 global.h 를 include 하여 어디서든 해당 기능을 접근할 수 있도록 한다.


- 미리 컴파일된 헤더

미리 컴파일된 헤더 기능은 자주 사용되면서 변경되지 않는 헤더 등을 미리 컴파일하는 기능으로, 프로젝트 내 다른 모든 cpp의 include 중 최상단에 위치해야 한다.

주로 vector 등의 STL이나 자주 사용할 헤더를 모아 둔 특정 헤더를 포함시킨다.

설정 방법은 다음과 같다:

  1. 같은 이름의 헤더 파일과 cpp 파일을 생성한다.

  2. cpp 파일에 #include (미리 컴파일된 헤더 파일) 를 한 뒤, cpp 속성에서 미리 컴파일된 헤더 옵션 설정을 만들기(/Yc), 헤더 파일을 앞서 생성한 헤더로 지정한 뒤 적용한다.




2. 엔진

게임의 기능이 main 의 메세지 루프에서 동작할 수 있도록 연결해주는 싱글톤 클래스이다.

초기화 시 윈도우를 생성하고 관리자 객체들을 초기화해 준다.

이후 메세지 루프에 들어서면 메세지가 없을 때 실제 게임 기능을 구현한 progress 함수가 호출된다.

progress 내부에서 각 프레임 별 수행할 함수의 호출이 이루어진다.


윈도우의 렌더링에 더블 버퍼링을 사용하기 위해 프론트 버퍼 비트맵과 백버퍼 비트맵, 그리고 각각의 DC를 소유하고 있다.

렌더링은 백버퍼에서 이루어지며, 이후 프레임의 마지막에 백버퍼의 비트맵을 프론트 버퍼로 복사하여 출력한다.




3. 관리자

관리자는 싱글톤 클래스로, 관리자 객체는 특정 기능을 담당하여 처리하는 창구 역할을 한다.

필요 시 초기화 함수로 초기에 설정해 두어야 하는 정보 및 기능을 세팅해 둘 수 있고, 이후 Tick 함수에서 프레임 당 호출 시 수행할 일을 구현한다.

관리자 객체의 예시는 다음과 같다:

  1. 시간 관리자: 초기화 단계에서 OS의 시간 갱신 주기를 확인하고, 이후 Tick 에서 매 프레임 당 소요 시간을 체크한다.

  2. 키 관리자: 초기화 단계에서 키보드의 키를 매핑한 뒤, 초기 상태를 설정해 둔다. 이후 Tick 에서 매 프레임마다 키 입력 상태를 일괄적으로 체크 및 갱신한다.

  3. 레벨 관리자: Level 객체를 관리하며, 구현된 레벨을 저장 및 관리하고, 현재 진행중인 레벨과 해당 레벨의 렌더링, 레벨의 교체 등 레벨 관련 기능을 수행한다.

  4. 태스크 관리자: 오브젝트의 생성 및 삭제, 레벨 변경 등 즉시 수행되는 기능이 아닌 프레임이 끝날 때 마지막으로 처리해야 하는 일들을 모아서 처리하는 관리자이다.


필요에 의해 기능 및 관리자가 얼마든지 추가되거나 변경될 수 있다.




4. 레벨

레벨은 오브젝트를 관리하는 객체이다.

여러 오브젝트들을 레이어 단위로 분류하여 가지고 있다.

레벨은 다음과 같은 기능을 수행한다:

  1. Begin 함수: 레벨이 처음 시작될 때 수행해야 하는 기능이 구현됨.

  2. Tick 함수: 레벨이 매 프레임마다 수행해야 하는 기능이 구현됨. 오브젝트의 Tick을 호출하는 등의 기능을 수행한다.

  3. FinalTick 함수: 레벨에 포함된 오브젝트의 FinalTick을 호출한다. 이는 오브젝트의 컴포넌트 Tick으로 연결된다.

  4. Render 함수: 레벨에서 윈도우에 표시 할 객체를 렌더링한다.




5. 오브젝트

오브젝트는 게임에 구현되는 각종 객체의 기본 클래스이다.

이후 게임에서 구현되는 플레이어, 몬스터, 아이템 등의 대부분의 객체는 오브젝트 클래스를 상속받아 구현된다.

가장 기본적인 이름, 크기, 위치, 소유 컴포넌트를 멤버로 가진다.

Begin, Tick, FinalTick, Render 함수는 각각 시작될 때, 매 프레임마다, 소유 컴포넌트의 수행할 동작과 렌더링을 담당한다.




6. 컴포넌트

컴포넌트는 프로그램에서 재사용이 가능한 독립된 모듈을 의미하며, 오브젝트에서 상속에 관계 없이 필요한 기능을 조합하여 사용할 수 있도록 구현되었다.

  1. Collider: 충돌체로써, 객체의 충돌 기능을 담당한다.

  2. RigidBody: 객체가 물리적 영향을 받을 수 있도록 한다.

  3. FlipBook: 스프라이트 등을 이용한 애니메이션의 출력 기능을 담당한다.


이 외에도 독립된 모듈로의 기능이 필요한 경우 추가될 수 있다.