5 이미지 리소스 생성 툴 <캐릭터 만들기>

5.3.4 기본 레이아웃 코드 살펴보기

이제 StartScene 화면의 UI를 작성하도록 하겠습니다. StartScene.cpp 파일에서 init() 메서드를 찾아 다음과 같이 수정합니다. ‘init’는 initialize의 약자로 초기화한다는 뜻입니다.

----------StartScene.cpp----------

// on "init" you need to initialize your instance

bool StartScene::init()

{

    //////////////////////////////

    // 1. super init first

    if (!Layer::init())

    {

        return false;

    }

 

    // 추후 코드 넣을

    /*****디바이스의 크기를 가져옵니다.*****/

    //Director 가져옵니다.

    auto director = Director::getInstance();

 

    //OpenGLView 가져옵니다.

    auto glview = director->getOpenGLView();

 

    //OpenGLView에서 DesignResolutionSize 가져옵니다.

    auto winSize = glview->getDesignResolutionSize();

 

    /*****배경 이미지 back 넣습니다.*****/

    //Sprite 생성하여 이미지를 불러옵니다.

    auto back = Sprite::create("title_bg.png");

 

    //back 해당 포인트에 위치시킵니다. 화면의 정중앙에 위치하도록 했습니다.

    back->setPosition(Point(winSize.width / 2, winSize.height / 2));

 

    //this back 자식 노드로 추가하였습니다.

    this->addChild(back);

 

    return true;

}

 

init()를 수정하였으면 디버거를 실행합니다. 배경(title_bg.png)이 추가된 것을 확인할 수 있습니다.

 

Figure 5‑12 배경을 추가한 실행 화면

위 소스 중 중요한 부분은 auto 키워드, create(), setPosition(), addChild() 부분입니다. 그리고 코드에 직접 나오지는 않지만 노드(Node)에 대해서도 살펴보고, 이후 사용할 setAnchorPoint()도 미리 알아보고 넘어가도록 하겠습니다. 앞으로도 계속 나오는 부분이니 꼭 숙지하기 바랍니다.

 

auto 키워드

auto 키워드는 C++ 11 버전부터 사용할 수 있는 키워드입니다. Cocos2d-x 3.0 버전에서부터 C++ 11을 지원합니다. auto 키워드를 사용하지 않아도 에러는 발생하지 않으나, auto 키워드를 사용하면 매우 편하고 소스 코드도 간결해지므로 꼭 숙지하고 사용하도록 합시다.

auto 키워드가 없는 기존의 방식은, 예를 들어 Sprite 객체의 경우 반드시 Sprite로 선언해야 했습니다. 즉 이런 식으로 선언해야만 했습니다.

 

Sprite *test = Sprite::create("test.png");

 

auto 키워드는 생성된 객체의 클래스에 따라 자료형을 자동으로 정해주기 때문에 매우 간편하게 사용할 수 있습니다.

 

auto test = Sprite:::create("test.png");

 

주의할 점은, auto 키워드는 선언과 초기화를 동시에 하는 경우에만 사용할 수 있다는 점입니다. 따라서 다음과 같이 사용할 수는 없다는 것을 알아두도록 합니다. 기존의 2.x 버전을 사용했던 분들은 헷갈릴 수 있으므로 참고하기 바랍니다.

 

//이렇게 사용하면 됩니다.

auto test;

test = Sprite:::create("test.png");

 

노드

노드(Node)는 Scene을 구성하는 기본 객체입니다. cocos2d-x의 Scene을 구성하는 대부분의 객체들은 이 Node를 상속받습니다. 예를 들어 화면을 구성하는 Sprite나 Layer 등 화면에 나타나야 하는 클래스들이 이 Node를 상속받습니다.

 

create()

create()는 노드나 액션 등 Cocos2d-x에서 사용하는 대다수의 클래스를 생성하는 메서드입니다. create()를 사용하여 객체를 생성하?메모리 해제를 수동으로 해주지 않아도 됩니다. 내부에서 자동으로 메모리를 해제해주는 autorelease() 코드가 들어 있기 때문입니다.

create()는 객체를 생성할 때 사용하는 메서드로 각 클래스마다 매개변수가 다르므로 형식에 맞추어 사용해야 합니다. Sprite의 경우 파일명을 매개변수로 넘깁니다.

 

setPosition()

setPosition()은 노드의 위치를 지정해주는 메서드입니다. 노드마다 사용하므로 꼭 알고 넘어갑시다. setPosition()은 Point를 매개변수를 받으며 Point는 x좌표와 y좌표를 가질 수 있습니다. 좌측 상단을 원점으로 잡는 언어들도 있지만, Cocos2d-x의 좌표계는 좌측 하단이 (0, 0)이고, 우측 상단이 (320, 480)이 됩니다.

 

(320, 480)

(0, 0)

Figure 5‑13 Cocos2d-x 좌표계

setAnchorPoint()

setAnchorPoint()는 앵커 포인트를 설정한다는 뜻이며, 앵커 포인트란 노드가 화면에 표시될 때 기준이 되는 점을 말합니다. 노드는 기본적으로 노드의 가운데를 기준으로 위치됩니다. x 및 y가 0에서 1 사이인 Point를 매개변수로 받습니다. Point(0.5, 0.5)는 노드의 정중앙입니다. 대부분의 노드들은 이 Point(0.5, 0.5)를 초기값으로 갖습니다. 하지만 Layer는 Point(0, 0)을 기본으로 갖습니다. 이 이유는 씬은 Layer를 상속받아 만들어집니다. 이 씬은 좌측 하단을 기준으로 위치하기에 Point(0, 0)을 기본값으로 갖습니다. 우리는 앞에서 배경 이미지(title_bg.png)를 화면 정가운데에 위치시켰습니다. 이 그림은 크기가 정확히 320 * 480인데, 어떻게 화면에 딱 맞게 들어갔을까요? back의 앵커 포인트가 기본값인 Point(0.5, 0.5)로서 이미지의 정중앙이므로, setPosition()을 사용하여 Point(winSize.width / 2, winSize.height / 2)로 위치시켰을 때 화면에 딱 맞게 표시된 것입니다.

 

    //back 해당 포인트에 위치시킵니다. 화면의 정중앙에 위치하도록 했습니다.

    back->setPosition(Point(winSize.width / 2, winSize.height / 2));

 

이 부분은 뒤에 실전에서 사용하는 부분에서 다시 한 번 설명하겠습니다.

 

addChild()

addChild() 메서드의 매개변수는 세 가지 종류가 있습니다.

virtual void addChild(Node *child);

virtual void addChild(Node *child, int localZOrder);

virtual void addChild(Node *child, int localZOrder, int tag);

 

하나씩 살펴보겠습니다. 첫 번째로 Node만 받는 경우입니다. 이때는 해당 노드만 자식으로 추가됩니다.

 

addChild(child);

 

두 번째는 Node와 ZOrder를 받습니다. 일반적으로 ZOrder를 입력하지 않은 경우 나중에 추가된 자식 노드가 위로 올라오게 되지만 ZOrder를 사용하면 순서를 조절할 수 있습니다.

 

addChild(child, 1);

 

세 번째는 Node, ZOrder, Tag를 입력으로 받습니다. Tag의 경우 setTag()를 이용하여 추가할 수도 있는데, 이렇게 addChild() 시 추가할 수도 있습니다. Tag 사용법은 추후에 설명하도록 하겠습니다.

 

addChild(child, 1, 3);

 

이상 세 가지를 필요한 상황에 맞추어 사용할 것입니다.

 

UI 작업을 진행하다 보면 경로나 파일명이 잘못됐을 경우 에러 메시지를 볼 수 있습니다. 이런 자주 발생하는 에러의 경우 비주얼 스튜디오의 출력창을 살펴보면 아래와 같은 메시지가 있을 겁니다. ErrorTest.png는 에러가 난 파일명입니다.

 

Get data from file(ErrorTest.png) failed

 

위와 같은 에러가 나오면 해당 경로나 파일명이 잘못되진 않았는지 확인해봅시다.

 

5.3.5 타이틀과 캐릭터 추가하기

 

배경 이미지만 있는 메인 화면은 썰렁하죠? 이제 init() 메서드 내부를 수정하여 타이틀과 캐릭터를 추가하겠습니다.

 

----------StartScene.cpp----------

    //this back 자식 노드로 추가하였습니다.

    this->addChild(back);

 

    /*****타이틀 title 넣습니다.*****/

    //Sprite 생성하여 이미지를 불러옵니다.

    auto title = Sprite::create("title_text.png");

 

    //앵커 포인트를 Point(0.5f, 1) 변경

    title->setAnchorPoint(Point(0.5f, 1));

 

    //title 해당 포인트에 위치시킵니다. 화면의 가로 중앙에 위치하도록 했습니다.

    title->setPosition(Point(winSize.width / 2, winSize.height - 30));

 

    //this title 자식 노드로 추가하였습니다.

    this->addChild(title);

 

    /*****캐릭터 character 넣습니다.*****/

    //Sprite 생성하여 이미지를 불러옵니다.

    auto character = Sprite::create("title_character.png");

 

    //character 해당 포인트에 위치시킵니다. 화면의 정중앙에 위치하도록 했습니다.

    character->setPosition(Point(winSize.width / 2, winSize.height / 2));

 

    //this character 자식 노드로 추가하였습니다.

    this->addChild(character);

 

    return true;

}

배경 이미지와 마찬가지로 Sprite를 이용하여 생성해주었습니다. 여기서는 title만 setAnchorPoint()로 앵커 포인트를 기본값인 정중앙 대신 Point(0.5f, 1)로 변경해봤습니다. setAnchorPoint()로 즉 다음 그림에서 화살표로 표시된 부분으로 앵커 포인트를 변경한 것입니다. 여기서는 차이를 확인하기 어렵지만 뒤에서 타이틀을 회전할 때는 앵커 포인트에 따른 차이를 시각적으로 확인할 수 있습니다.

 

Figure 5‑14 앵커 포인트

 

앵커 포인트의 매개변수는 0에서 1 사이의 값을 사용하며 0은 처음, 1은 끝을 나타냅니다. 0.5는 물론 그 가운데를 나타냅니다. 이 값을 퍼센트라고 생각하면 이해하기 쉽습니다. 1=100%, 0=0%, 0.5=50%처럼 말이죠.

 

Figure 5‑15 앵커 포인트

 

title->setPosition을 보면 y 위치가 winSize.height에서 30만큼 뺀 곳입니다. 이것은 곧 화면 위에서 30만큼 아래로 떨어진 곳에 위치하라는 뜻입니다.

이제 디버거를 실행해보면 배경 이미지 위에 타이틀과 캐릭터가 추가된 것을 볼 수 있습니다.

 

Figure 5‑16 타이틀과 캐릭터를 넣은 실행 화면

지금까지 본 실행 화면 좌측 하단을 살펴보면 GL verts, GL calls, 그리고 숫자가 있습니다. GL verts란 3D에서 사용하는 버텍스의 개수 입니다. 버텍스란 폴리곤의 꼭짓점이 만나는 곳을 뜻하며, 이 버텍스가 18개가 사용되었다는 의미입니다. GL calls란 OpenGL이 호출되는 횟수입니다. 즉 노드의 개수라고 볼 수 있습니다. 맨 아래 숫자는 FPSframes per second, 즉 초당 화면이 갱신되는 횟수입니다. 60.1이란 60 FPS라는 뜻이죠. 디버깅 시 이 숫자를 모니터링하며 현재 화면의 노드 개수와 FPS를 확인하고 퍼포먼스에 문제가 없는지 살펴볼 수 있습니다.

물론 프로그램을 배포할 때는 저런 표시가 남아 있으면 안 되겠죠. 이를 표시하지 않기 위해서는 AppDelegate.cpp 파일을 수정해야 합니다. 다음 라인을 찾아 true를 false로 바꿔주면 됩니다.

 

    // turn on display FPS

    director->setDisplayStats(false);

 


Prev | Next