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

5.3.8 캐릭터 만들기 화면으로 이동 구현하기

5.3.1을 참고하여 CharacterScene이라는 이름의 클래스를 만듭니다.

 

Figure 5‑22 CharacterScene 클래스를 추가한 모습

 

CharacterScene.h 파일과 CharacterScene.cpp 파일을 생성하였으면 StartScene.h 파일과 StartScene.cpp 파일의 내용을 붙여넣고, Cocos2d-x에서 사용할 수 있도록 빈 Scene을 만듭니다.

먼저 헤더 파일을 보면, 다음과 같이 클래스명을 두 군데 수정하고, onClickButton2() 선언은 삭제합니다.

 

----------CharacterScene.h----------

#include "cocos2d.h"

 

class CharacterScene: public cocos2d::Layer

{

public:

    // there's no 'id' in cpp, so we recommend returning the class instance pointer

    static cocos2d::Scene* createScene();

 

    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone

    virtual bool init();

 

    // a selector callback

    void menuCloseCallback(cocos2d::Ref* pSender);

 

    // implement the "static create()" method manually

    CREATE_FUNC(CharacterScene);

 

    // 삭제

};

 

cpp 파일 역시 다음과 같이 클래스명을 수정하고, 사용하지 않는 코드 및 콜백 메서드 onClickButton2()는 삭제합니다.

 

----------CharacterScene.cpp----------

#include "CharacterScene.h"

 

USING_NS_CC;

 

Scene* CharacterScene::createScene()

{

    // 'scene' is an autorelease object

    auto scene = Scene::create();

 

    // 'layer' is an autorelease object

    auto layer = CharacterScene::create();

 

    // add layer as a child to scene

    scene->addChild(layer);

 

    // return the scene

    return scene;

}

 

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

bool CharacterScene::init()

{

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

    // 1. super init first

    if (!Layer::init())

    {

        return false;

    }

 

    // 추후 코드 넣을

 

    return true;

}

 

// 삭제

 

이와 같이 두 파일을 수정했으면 StartScene에서 [캐릭터 만들기] 버튼을 눌렀을 때 CharacterScene을 호출하도록 추가해야 합니다. StartScene.cpp 파일을 아래와 같이 수정합니다.

 

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

#include "StartScene.h"

#include "CharacterScene.h"

 

…중략…

 

//버튼 추가

auto button1 = MenuItemImage::create("title_btn_1.png", "title_btn_1_on.png", "title_btn_1_dis.png", [&](Ref *sender) {

    log("onClickButton1");

    auto Scene = CharacterScene::createScene();

    Director::getInstance()->pushScene(Scene);

});

 

클레스를 호출하기 위해서는 먼저 그 헤더 파일을 #include해야 합니다(①). 그리고 button1의 람다 부분에 CharacterScene을 호출하는 코드를 추가했습니다(②).

여기서 pushScene()은 해당 Scene을 추가하는 메서드입니다. replaceScene()을 사용할 수도 있습니다. pushScene()은 기존의 Scene 위에 Scene을 추가하는 방식이고, replaceScene()은 기존 Scene을 없애고 Scene을 추가하는 방식이라는 점이 다릅니다.

이제 디버거를 실행하고, [캐릭터 만들기] 버튼을 누르면 검정 화면으로 이동할 것입니다. 우리의 예상대로, 이 아무것도 없는 검정 화면이 바로 CharacterScene입니다.

 

  ->  

Figure 5‑23 캐릭터 만들기 화면으로 이동

5.3.9 화면 전환 애니메이션 효과 넣기

 

화면이 그냥 전환되는 것보다 화면 전환에 효과를 추가하는 것이 좀 더 화려하게 보일 것입니다.

화면 전환에 애니메이션을 추가해보겠습니다. CharacterScene을 호출하는 곳, 즉 button1의 람다 부분에서 auto Scene = CharacterScene::createScene();를 아래와 같이 수정합니다.

 

    auto Scene = TransitionCrossFade::create(0.5f, CharacterScene::createScene());

 

TransitionCrossFade 클래스를 사용하여 크로스페이딩 애니메이션을 추가하였습니다. TransitionCrossFade::create()의 첫 번째 매개변수는 시간(초)이고, 두 번째 매개변수는 호출할 메서드입니다.

디버거를 실행하고 [캐릭터 만들기] 버튼을 눌러보면 화면 전환에 애니메이션 효과가 추가된 것을 볼 수 있습니다.

      

Figure 5‑24 애니메이션 추가 화면

 

크로스페이딩 애니메이션을 위한 TransitionCrossFade 클래스 외에도 TransitionFlipX, TransitionFlipY, TransitionJumpZoom 등 여러 가지 애니메이션 클래스가 있습니다. 앞에서 TransitionCrossFade 클래스를 사용한 곳에 다른 클래스를 넣으면 눈으로 확인할 수 있습니다.

 

auto Scene = TransitionFlipX::create(0.5f, CharacterScene::createScene());

auto Scene = TransitionFlipY::create(0.5f, CharacterScene::createScene());

auto Scene = TransitionFlipZumpZoom::create(0.5f, CharacterScene::createScene());

 

예를 들어 이와 같은 세 가지 애니메이션을 적용해보면 다음과 같은 화면 전환 효과를 확인할 수 있을 것입니다.

 

      

Figure 5‑25 화면 전환 애니메이션 예시(TransitionFlipX, TransitionFlipY, TransitionJumpZoom)

 

다른 애니메이션을 추가하고 싶다면 레퍼런스 문서를 찾아보는 것이 편리하고 정확합니다. 레퍼런스 문서는 Cocos2d-x 사이트(http://www.cocos2d-x.org/)에서 버전별로 찾아볼 수 있습니다. 이 책에서 다루는 3.4 버전의 경우 레퍼런스 메인 페이지 주소는 http://www.cocos2d-x.org/reference/native-cpp/V3.4/index.html입니다. 여기에서 우측 상단의 검색창에 ‘transition’을 입력하면 관련 클래스들을 모두 볼 수 있습니다(검색 결과 페이지 http://bit.ly/1QNpi1a).

 

5.3.10 타이틀 화면에 애니메이션 적용하기

타이틀 화면의 UI 구현이 끝났습니다. 이제 마지막으로 타이틀 화면을 좀 더 시각적으로 돋보이게 하는 애니메이션 효과를 추가해보겠습니다.

StartScene.cpp 파일에서 init() 메서드를 아래와 같이 수정합니다.

 

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

//생성된 버튼을 메뉴에 추가한다.

    auto menu = Menu::create(button1, button2, NULL);

    menu->setPosition(Point::ZERO);

    this->addChild(menu);

 

    //타이틀 스프라이트에 애니메이션 추가

    auto to = title->getPosition();

    auto from = Point(to.x, to.y + 100);

    //title 스프라이트의 시작 위치를 지정

    title->setPosition(from);

 

    //MoveTo 지정된 노드를 해당 위치로 움직이는 액션을 만든다.

    auto action = MoveTo::create(0.5f, to);

    //title 스프라이트에 액션 지정

    title->runAction(action);

 

    return true;

}

 

 

먼저 title의 위치를 가져와서 to라는 포인트에 추가해주고, from은 애니메이션이 시작할 위치, 즉 100픽셀 위로 지정했습니다(①).

그다음 액션을 담을 변수 action을 생성했는데, create()의 매개변수로는 시간과 이동할 위치를 지정해줍니다(②). 액션이란 쉽게 말해 에니메이션이라고 생각하면 됩니다. 바로 이어서 자세히 설명하도록 하겠습니다. 바로 앞에서 살펴봤던 Transition 계열 클래스처럼, 대부분의 애니메이션은 생성 시 첫 번째 매개변수로 시간을 받습니다.

 

이제 디버거를 실행해보면 타이틀이 상단에서부터 아래로 내려오는 애니메이션이 추가되었습니다(금방 지나가므로 실행 직후 잘 지켜봐야 합니다).

 

    

Figure 5‑26 타이틀에 애니메이션 적용

 

액션에 관련된 클래스인 Action에는 여러 가지 애니메이션이 있습니다. 기본적인 이동, 회전, 크기 변경 등의 애니메이션이 있으며 이러한 애니메이션을 여러 개 섞어 사용할 수도 있습니다.

여러 애니메이션을 사용할 때 사용되는 클래스 중에는 Spawn과 Sequence가 있습니다. Spawn은 애니메이션을 동시에 실행하며, Sequence는 순차적으로 실행한다는 차이가 있습니다. 간단히 살펴보겠습니다. 해당 부분을 이렇게 고쳐봅시다.

 

    //MoveTo 지정된 노드를 해당 위치로 움직이는 액션을 만든다.

    auto action = Sequence::create(MoveTo::create(0.5f, to), RotateTo::create(0.5f, 720), NULL);

 

앞에서 언급한 적이 있지만, 매개변수를 여러 받을 있는 메서드는 마지막에 NULL을 추가하여 끝을 알려주어야 합니다.

그럼 디버거를 실행하여 확인해볼까요? MoveTo 애니메이션이 끝난 다음에 RotateTo(회전) 애니메이션이 실행됩니다.

 

      

      

Figure 5‑27 복합 애니메이션 적용

 

만약 Sequence 클래스 대신 Spawn 클래스를 사용하면 MoveTo 애니메이션과 RotateTo 애니메이션이 동시에 적용되는 것을 확인할 수 있을 것입니다. 두 개뿐만 아니라 세 개, 네 개, 그 이상의 애니메이션을 추가하여 사용할 수도 있습니다.

 

여기서 회전 애니메이션이 동작하는 것을 잘 살펴보면 앵커 포인트로 지정한 곳을 기준으로 회전하는 것을 볼 수 있습니다. 우리는 앞에서(5.3.5) title의 앵커 포인트를 Point(0.5f, 1), 즉 가로 중간, 세로 상단으로 지정했습니다. 다음과 같이 title의 앵커 포인트를 정중앙으로 수정하면 어떻게 될까요? 앵커 포인트가 아래로 내려옴에 따라 타이틀의 위치 역시 아래로 더 내렸습니다.

 

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

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

 

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

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

 

디버거를 실행해보면, 회전 애니메이션의 기준점이 바뀐 것을 눈으로 잘 확인할 수 있습니다.

 

   

Figure 5‑28 기준점 변경 후 회전 애니메이션

 


Prev | Next