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;
Scene* ModalTopScene::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を押した場面
コメントをお書きください