지난번 연재 5-1과 이어집니다. 그림번호는 새로 시작됩니다.
지금부터 개발은 기본적으로 비주얼 스튜디오에서 진행되며, 4장에서 설정을 마치고 생성해놓은 minigame 위에서 진행합니다.
먼저 화면의 크기를 설정하는 것부터 시작하겠습니다. 솔루션 탐색기에서 minigame 아래 src 경로의 AppDelegate.cpp를 선택하면 왼쪽 코드 창에 코드가 뜰 것입니다. AppDelegate.cpp는 앱의 기본 정보를 정의하는 클래스 파일입니다. 앱이 실행되면 이 AppDelegate에 정의된 속성에 맞추어 앱이 실행됩니다. 따라서 앱 전체의 속성을 제어하는 부분이 바로 이 AppDelegate입니다.
Figure 5‑1 솔루션 탐색기
솔루션 탐색기에 표시되는 경로명과 실제 파일이 위치한 폴더는 약간씩 차이가 있습니다. 솔루션 탐색기상의 src 경로는 클래스 파일들이 위치하는 경로로서, 실제로 디스크에 있는 폴더명은 Classes입니다(버전에 따라 Classes라고 표시되는 버전도 있지만, 이 책에서 다루는 3.4 버전에서는 src라고 표시됩니다).
소스 코드에서 노란색 형광색으로 표시한 곳이 수정(또는 추가, 삭제)할 부분입니다. 이하 코드 내 형광색 표시된 부분에 순서대로 ①, ②, ③...이 있다고 생각해주세요!
----------AppDelegate.cpp----------
static Size designResolutionSize = Size(320, 480);
bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview) {
glview = GLViewImpl::createWithRect("My Game", Rect(0, 0, designResolutionSize.width, designResolutionSize.height));
director->setOpenGLView(glview);
}
// Set the design resolution
glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::SHOW_ALL);
// turn on display FPS
director->setDisplayStats(true);
// set FPS. the default value is 1.0/60 if you don't call this
director->setAnimationInterval(1.0 / 60);
// create a scene. it's an autorelease object
auto scene = HelloWorld::createScene();
// run
director->runWithScene(scene);
return true;
}
먼저 designResolutionSize는 내용이 표시될 화면의 크기를 정의하는 Size 클래스의 정적 멤버변수입니다(①). 여기서는 가로 320, 세로 480으로 정의했습니다. 이 코드를 applicationDidFinishLaunching() 메서드(25행) 위에 추가해주면 됩니다.
그다음 create() 메서드 부분을 createWithRect()로 바꿔서, 앞에서 정의한 너비 및 높이에 해당하는 사각형을 glview에 넘겨 그 사각형에 해당하는 크기의 창(윈도우의 경우)을 생성하라고 지시했습니다(②).
그 아래에는 glview의 setDesignResolutionSize() 메서드에 너비, 높이, 정책을 넘겨서 화면 표시 영역과 화면 표시 정책을 설정하는 코드를 추가했습니다(③). 표시 영역은 창 크기와 동일한 너비와 높이로 설정했고, 표시 정책은 SHOW_ALL을 지정했습니다.
표시 정책이란 다중 해상도 및 가로 세로 비율에 관한 것으로, SHOW_ALL이란 말 그대로 표시되는 가로 세로 비율을 유지한 채 확대/축소하여 모든 것을 화면에 보여주는 정책입니다. 표시 영역과 창 크기의 화면비가 다를 경우 위아래 또는 좌우가 빈 공간(레터박스)으로 채워집니다.
다른 정책으로는 EXACT_FIT이나 NO_BORDER가 있습니다. EXACT_FIT은 가로 세로 비율을 무시하고 창 크기에 표시 영역을 똑같이 맞춥니다. 따라서 레터박스는 없지만, 옆으로 늘어나거나 위로 늘어나서 화면이 이상해 보일 수도 있습니다. NO_BORDER는 화면비를 유지한다는 점에서 SHOW_ALL과 비슷합니다. 다만 표시 영역과 창 크기의 화면비가 다를 경우 빈 공간을 넣는 대신 위아래 또는 좌우 일부를 자릅니다.
이렇게 코드를 수정했으니 실행해봐야겠죠? ‘디버그>디버깅 시작’을 선택합니다. 단축키는 F5입니다.
Figure 5‑2 디버그>디버깅 시작
만약 디버거가 이미 실행 중이면 디버그>다시 시작을 선택하면 됩니다. 단축키는 Ctrl + Shift + F5입니다. 이 두 가지 단축키는 많이 사용하기 때문에 외워두는 것이 좋습니다.
Figure 5‑3 디버그>다시 시작
디버그>디버깅 시작: F5
디버그>다시 시작: Ctrl + Shift + F5
실행 화면을 보면 320 × 480으로 윈도우 크기가 바뀐 것을 확인할 수 있습니다. 앞에서 화면 크기를 바꾸지 않고 처음 코드 그대로 실행했던 화면(그림 4-11)과 비교해보세요.
Figure 5‑4 창 크기 변경 후 실행 화면
게임을 개발하기 위해서는 게임 화면을 구성하는 리소스가 필요합니다. 이 책에서는 미리 제공하는 리소스를 다운로드하여 사용할 것입니다. 게임 개발에 사용할 리소스는 다음 주소에서 다운로드할 수 있습니다.
https://download.hanbit.co.kr.co.kr/exam/cocos2d-x/
5장에 해당하는 5.2.2 리소스 파일을 다운로드하여 압축을 풉니다. 이를 5.2.2 폴더 아래 Resources 폴더로 이동합니다.
Figure 5‑5 리소스 파일 압축을 푼 폴더\5.2.2\Resources
iphone, iphone_retina, sound 폴더 및 아이콘 파일들이 있을 것입니다. 파일을 전체 선택한 다음 복사하여 minigame의 프로젝트 폴더 아래 Resources 폴더에 붙여넣습니다. 그대로 따라 했다면 c:\cocos2d-x-3.4\projects\minigame일 것입니다.
Figure 5‑6 c:\cocos2d-x-3.4\projects\minigame\Resources
이 리소스 파일 중 iphone 폴더에는 320 × 480 크기의 이미지들이 들어 있고 iphone_retina 폴더에는 640 × 960 크기의 이미지들이 들어 있습니다. 비주얼 스튜디오로 개발 시 이러한 리소스 파일들을 따로 프로젝트에 추가할 필요는 없습니다. 곧바로 살펴보듯, 소스 코드 내에서 해당 폴더를 참조하기만 하면 됩니다.
리소스 폴더에 파일들을 옮겨놨으면 게임이 디바이스와 운영체제에 따라 리소스 폴더를 참조할 수 있도록 설정해야 합니다. 이 역시 AppDelegate.cpp 파일에서 이뤄집니다. 아래와 같이 코드를 추가합니다.
----------AppDelegate.cpp----------
typedef struct tagResource
{
Size size;
char directory[100];
}Resource;
static Size designResolutionSize = Size(320, 480);
static Resource smallResource = { Size(320, 480), "iphone" };
static Resource mediumResource = { Size(640, 960), "iphone_retina" };
bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview) {
glview = GLViewImpl::createWithRect("My Game", Rect(0, 0, designResolutionSize.width, designResolutionSize.height));
director->setOpenGLView(glview);
}
// Set the design resolution
glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::SHOW_ALL);
Size frameSize = glview->getFrameSize();
// frameSize가 smallResource보다 작거나 같으면 smallResource를 사용한다.
std::vector<std::string> resDirOrders;
if (frameSize.height <= smallResource.size.height){
resDirOrders.push_back(smallResource.directory);
director->setContentScaleFactor(smallResource.size.height / designResolutionSize.height);
}
// frameSize가 smallResource보다 크면 mediumResource를 사용한다.
else{
resDirOrders.push_back(mediumResource.directory);
director->setContentScaleFactor(mediumResource.size.height / designResolutionSize.height);
}
FileUtils::getInstance()->setSearchResolutionsOrder(resDirOrders);
// turn on display FPS
director->setDisplayStats(true);
먼저 리소스 참조에 쓰일 구조체 Resource를 정의했습니다(①).
이를 이용해 320 × 480용 폴더를 참조하는 smallResource와 그보다 큰 기기용으로 mediumResource를 정의했습니다(②).
다음으로 getFrameSize()로 디바이스의 높이를 구한 다음, 그 높이를 기준으로 해당하는 리소스 폴더를 참조하게 했습니다(③). 즉 높이가 480 이하인 디바이스에서는 iphone 폴더를, 높이가 480보다 크면 iphone_retina 폴더를 사용하도록 하였습니다.