2015年

3月

10日

Cocos2d-x Ver 3.x モーダルレイヤー(アラートビュー)の作成

Cocos2d-xには、iOSのようなUIAlertViewはありませんのでモーダルレイヤを制作することになります。簡単な例のモーダルレイヤを制作しましたので参考にしてください。

ModalTopSceneからModalLayerとメニュー表示します。

ModalLayerのメニューからModalSecondSceneを表示やキャンセルするとModalTopSceneに戻ることが出来ます。

Cocos2dx 3.x C++言語
ModalTopScene.hを次のように変更してみてください。

#ifndef __Modal__ModalTopScene__

#define __Modal__ModalTopScene__


#include "cocos2d.h"


// 名前空間 #define USING_NS_CC using namespace cocos2d

USING_NS_CC;


class ModalTopScene : public Layer

{

    

public:

    

    // 初期化のメソッド

    virtual bool init();

    

    static cocos2d::Scene* createScene();

    

    // create()を使えるようにしている。

    CREATE_FUNC(ModalTopScene);

};


#endif /* defined(__Modal__ModalTopScene__) */


ModalTopScene..cppを次のように変更してみてください。

#include "ModalTopScene.h"

#include "ModalLayer.h"


// 名前空間 #define USING_NS_CC using namespace cocos2d

USING_NS_CC;


Scene* ModalTopScene::createScene()

{

    // 「シーン」は自動解放オブジェクトです

    auto scene = Scene::create();

    

    // 「レイアウト」は自動解放オブジェクトです

    auto layer = ModalTopScene::create();

    

    // シーンに子としてレイヤーを追加

    scene->addChild(layer);

    

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

    // モーダルレイヤーを追加

    auto modalLayer = ModalLayer::create();

    scene->addChild(modalLayer);

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

    

    // シーンを返す

    return scene;

}


// INIT」初期化

bool ModalTopScene::init()

{

    if ( !Layer::init() )

    {

        return false;

    }

    

    // 画面サイズを取得

    Size winSize = Director::getInstance()->getVisibleSize();

    

    auto Sprite = Sprite::create("Default-568@2x.png");

    Sprite->setPosition(Vec2(winSize.width/2, winSize.height/2));

    this->addChild(Sprite);

    

    return true;

}


ModalLayer.hを次のように変更してみてください。

#ifndef __Modal__ModalLayer__

#define __Modal__ModalLayer__


#include "cocos2d.h"


// 名前空間 #define USING_NS_CC using namespace cocos2d

USING_NS_CC;


class ModalLayer : public cocos2d::Layer

{

    

public:


    virtual bool init();

    

    void menuCloseCallback(Ref* pSender);

    

    void pushMenu01(Ref *pSender);

    

    // create()を使えるようにしている。

    CREATE_FUNC(ModalLayer);

};


#endif /* defined(__Modal__ModalLayer__) */


ModalLayer.cppを次のように変更してみてください。

#include "ModalLayer.h"

#include "ModalSecondScene.h"

using namespace cocos2d;


bool ModalLayer::init()

{

    if ( !CCLayer::init() )

    {

        return false;

    }

    

    Size winSize = Director::getInstance()->getVisibleSize();

    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    

    // モーダルのフレーム

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

    frame->setPosition(Vec2(winSize.width/2, winSize.height/2));

    this->addChild(frame);

    //透明度を変更(0~255)

    frame->setOpacity(220);

    

    // Menu1

    auto button01 = MenuItemImage::create("menu-image1.png"// 通常状態の画像

                                            "menu-image1-hover.png"// 押下状態の画像

                                            CC_CALLBACK_1(ModalLayer::pushMenu01, this));

    // Menu2

    auto button02 = MenuItemImage::create("menu-image2.png"// 通常状態の画像

                                             "menu-image2-hover.png"// 押下状態の画像

                                             CC_CALLBACK_1(ModalLayer::pushMenu01, this));

    // キャンセル

    auto closeItem00 = MenuItemImage::create("menu-image9.png"// 通常状態の画像

                                             "menu-image9-hover.png"// 押下状態の画像

                                             CC_CALLBACK_1(ModalLayer::menuCloseCallback, this));

    

    // ボタンの設置

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

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

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

    

    auto menu = Menu::create(button01, button02, closeItem00, NULL);

    menu->setPosition(Vec2::ZERO);

    this->addChild(menu, 1);


    // モーダル処理

    auto listener = EventListenerTouchOneByOne::create();

    listener->setSwallowTouches(true);

    listener->onTouchBegan = [](Touch *touch,Event*event)->bool{

        return true;

    };

    auto dispatcher = Director::getInstance()->getEventDispatcher();

    dispatcher->addEventListenerWithSceneGraphPriority(listener, this);

    

    return true;

}


// menuCloseCallback ModalLayerオブジェクトの削除

void ModalLayer::menuCloseCallback(Ref* pSender)

{

    // ModalLayerオブジェクトの削除

    this->removeFromParentAndCleanup(true);

}


// pushStart01ボタン

void ModalLayer::pushMenu01(Ref *pSender)

{

    CCLOG("pushMenuボタン01");

    

    // 遷移先の画面のインスタンス

    Scene *pScene = ModalSecondScene::createScene();

    

    // 0.5秒かけてフェードアウトしながら次の画面に遷移します

    //    引数1:フィードの時間

    //    引数2:移動先のシーン

    //    引数3:フィードの色(オプション)

    TransitionFade* transition = TransitionFade::create(0.5f, pScene);

    

    // 遷移実行  遷移時のアニメーション

    // 直前のsceneはもう使わないから捨ててしまう方法。基本はこれになります。

    Director::getInstance()->replaceScene(transition);

}

ModalSecondScene.hを次のように変更してみてください。

#ifndef __Modal__ModalSecondScene__

#define __Modal__ModalSecondScene__


#include "cocos2d.h"


// 名前空間 #define USING_NS_CC using namespace cocos2d

USING_NS_CC;


class ModalSecondScene : public Layer

{

    

public:

    

    // 初期化のメソッド

    virtual bool init();

    

    static cocos2d::Scene* createScene();

    

    // create()を使えるようにしている。

    CREATE_FUNC(ModalSecondScene);

};



#endif /* defined(__Modal__ModalSecondScene__) */


ModalSecondScene.cppを次のように変更してみてください。

#include "ModalSecondScene.h"

// 名前空間 #define USING_NS_CC using namespace cocos2d

USING_NS_CC;


Scene* ModalSecondScene::createScene()

{

    // 「シーン」は自動解放オブジェクトです

    auto scene = Scene::create();

    

    // 「レイアウト」は自動解放オブジェクトです

    auto layer = ModalSecondScene::create();

    

    // シーンに子としてレイヤーを追加

    scene->addChild(layer);

    

    // シーンを返す

    return scene;

}


// INIT」初期化

bool ModalSecondScene::init()

{

    if ( !Layer::init() )

    {

        return false;

    }

    

    // 画面サイズを取得

    Size winSize = Director::getInstance()->getVisibleSize();

    

    // バックグランドカラー

    auto background = LayerColor::create(Color4B::BLUE,

                                         winSize.width,

                                         winSize.height);

    // バックグランドカラー 第2引数は表示順

    this->addChild(background, 0);

    

    return true;

}


ポイントは、ModalTopScene.cppにモーダルレイヤーを追加することです。

ModalTopSceneが起動すると追加したモーダルレイヤーが起動しモーダルが表示されます。

#include "ModalTopScene.h"

#include "ModalLayer.h"


USING_NS_CC;


SceneModalTopScene::createScene()

{

    // 「シーン」は自動解放オブジェクトです

    auto scene = Scene::create();

    

    // 「レイアウト」は自動解放オブジェクトです

    auto layer = ModalTopScene::create();

    

    // シーンに子としてレイヤーを追加

    scene->addChild(layer);

    

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

    // モーダルレイヤーを追加

    auto modalLayer = ModalLayer::create();

    scene->addChild(modalLayer);

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

    

    // シーンを返す

    return scene;

}

 

GitHub Modal

キャンセルボタンを押した場面

Menu1,Menu2を押した場面

  

目 次