Cocos2d-x　入門編-画面遷移

画面遷移は、Directorクラスの提供する画面遷移用の関数を利用して行います。
具体的な例をあげて説明していきたいと思います。

#初期画面表示について
アプリアイコンタップ後、最初に表示する初期画面表示はAppDelegate.cpp #applicationDidFinishLaunching()にて、最初に表示したいシーンを作成して表示するようにする必要があります。

①最初に表示したいシーンを作成する。
②Directorクラスの#runWithSceneという関数を利用して初期表示画面を表示する。

```
AppDelegate.cpp
#applicationDidFinishLaunching()

auto director = Director::getInstance();

//初期画面表示
auto scene = HelloWorld::createScene();
director->runWithScene(scene);
```

#画面遷移について
##画面を都度破棄して表示するような画面遷移の例
1.必要なシーンごとのソースファイルを用意する
今回は、Splash画面,Top画面、ホーム画面用のシーンを用意してみましょう。

- SplashScene
- TopScene
- HomeScene

2.アプリ起動時にSplashSceneを呼び出す。

```
AppDelegate.cpp
#applicationDidFinishLaunching()

auto director = Director::getInstance();
auto scene = SplashScene::createScene();
director->runWithScene(scene);
```

3.Splash画面表示数秒後TopSceneを表示する。
よくゲームアプリである、ゲーム会社のロゴ表示や、各種データ初期化後にTop画面に遷移するのが一般的だと思いますが、今回は3秒後にTop画面に遷移するようにしています。

```
SplashScene.cpp

#include "SplashScene.h"
#include "TopScene.h"

Scene *SplashScene::createScene(){
    auto scene = Scene::create();
    auto layer = SplashScene::create();
    scene->addChild(layer);
    return scene;
}

bool SplashScene::init(){

    if (! Layer::init()) {
        return false;
    }
    
    // 画面サイズを取得
    Size winSize = Director::getInstance()->getWinSize();
    Point origin = Director::getInstance()->getVisibleOrigin();

    //背景
    auto background = Sprite::create("splash.png");

    //中央に表示されるように座標を設定
    background->setPosition(Point(winSize.width /2 ,winSize.height/2));
    this->addChild(background, 0);

    // タイトル画面に画面遷移する
    this->scheduleOnce(schedule_selector(SplashScene::changeTitleScene), 3.0f);
    return true;
}

void SplashScene::changeTitleScene(float millsecond){
    
    //画面遷移する。
    auto scene = TopScene::createScene();
    
    // 0.5秒かけてホワイトアウトしてタイトルに移動する
    TransitionFade* fade = TransitionFade::create(0.5f, scene, Color3B::WHITE);

    //SplashSceneを破棄してTopSceneに遷移する
    Director::getInstance()->replaceScene(fade);
}

```

4.Touch To StartボタンタップでHomeSceneを表示する。
よくあるゲームアプリのTop画面のStartボタンのように点滅アクションを設定してみました。
ボタンタップ時のCallbackにて、pushBtnCallback()が呼ばれてHome画面に遷移するようにしています。

```
TopScene.cpp

#include "TopScene.h"
#include "HomeScene.h"

Scene *TopScene::createScene(){
    auto scene = Scene::create();
    auto layer = TopScene::create();
    scene->addChild(layer);
    return scene;
}

bool TopScene::init(){

    if (! Layer::init()) {
        return false;
    }

    //画面サイズを取得
    Size winSize = Director::getInstance()->getWinSize();
    Point origin = Director::getInstance()->getVisibleOrigin();

    auto background = LayerColor::create(Color4B::WHITE, winSize.width, winSize.height);
    this->addChild(background, 0);

    //タイトル
    Label *label = Label::createWithSystemFont("タイトル", "Arial", 10);
    label->setColor(Color3B::BLACK);
    
    label->setPosition(Point(winSize.width / 2, winSize.height/ 1.5));
    this->addChild(label, 1);

    // スタートボタン
    auto startButton = MenuItemImage::create(
                                             "touchtostart.png",  // 通常状態の画像
                                             "touchtostart.png",  // 押下状態の画像
                                             CC_CALLBACK_1(TopScene::pushBtnCallback, this)); // 押下時のアクション

    // ボタンの設置
    startButton->setPosition(Point(winSize.width * 0.5 , winSize.height * 0.15));
    auto menu = Menu::create(startButton, NULL);
    menu->setPosition(Point::ZERO);
    
    this->addChild(menu, 2);

    // Startボタンの点滅アクション
    auto actionBlink = Blink::create(3, 5);
    auto repeat = Repeat::create(actionBlink, -1);
    startButton->runAction(repeat);
    return true;
}


void TopScene::pushBtnCallback(Ref *object){
    CCLOG("スタートボタンが押された");

    auto scene = HomeScene::createScene();
    
    // 0.5秒かけてホワイトアウトしてTopSceneに遷移させる
    TransitionFade* fade = TransitionFade::create(0.5f, scene, Color3B::WHITE);
    
    //Splashを破棄してTopSceneに遷移する
    Director::getInstance()->replaceScene(fade);   
}

```

##別のシーンに遷移して前のシーンに戻る場合
Help画面や、課金アイテムの選択画面などに遷移して課金処理完了後、前画面に戻る場合は前項で説明したreplaceSceneだと、画面を破棄して遷移しているため前画面に戻る場合は状態などが保持されないので(※状態やデータなどを管理すればできるかもしれませんが考慮が必要)
pushSceneを利用して画面遷移するようにすることで解決することができます。

```
auto scene = HelpScene::createScene();
Director::getInstance()->pushScene(scene);
```

因みに、pushSceneは、画面遷移の際のアニメーションをreplaceSceneのように指定できないようなので、CCDirectionを継承したクラスを作成してアニメーションさせればいいようです。

http://blog.mogmet.com/cocos2dx-popscene-with-transition-without-improve-library/

#画面遷移アニメーションについて
cocos2dでは画面遷移する際にアニメーションをつけることができます。
デフォルトでいくつか用意されていますが、既存のアニメーション用のクラスもしくは、TransitionSceneを継承して独自にアニメーションを実現することもできるかと思います。

・CCTransitionFade：フェードイン
・CCTransitionFlipX：X軸方向に回転する
・CCTransitionFlipY：Y軸方向に回転する
・CCTransitionPageTurn:ページをめくるようなアニメーション
・CCTransitionSlideInL：次画面が左からスライドする
・CCTransitionSlideInR：次画面が右からスライドする
・CCTransitionSlideInT：次画面が上からスライドする
・CCTransitionSlideInB：次画面が下からスライドする
・CCTransitionRotoZoom：画面が縮小して消える

<フェードインの場合の例>

```
// 0.5秒かけてホワイトアウトしてTopSceneに遷移させる
TransitionFade* fade = TransitionFade::create(0.5f, scene, Color3B::WHITE);
    
//Splashを破棄してTopSceneに遷移する
Director::getInstance()->replaceScene(fade);   
```