Roll Play My Life

= ryuji_026

cocos2d-xでモーダルダイアログのつくりかた

追記 これはv2.1.4で試したやつで、v3.0では cocos2d-x 3.x モーダルレイヤ - Roll Play My Life ←こうやった。


モーダルレイヤーみたいなクラスがあると便利。モーダルダイアログというのは、表示すると後ろにあるボタンとかが操作できなくなるダイアログのことで、ゲーム中のオプション画面とか、サブメニューみたいなの出すのに使える。

ModalLayer* layer = ModalLayer::create;

とかいう感じになればいいとのこと。これを継承してレイヤーを定義すれば様々なモーダルダイアログが作れるといった感じになる。

そもそも、なんで上にレイヤー出しても後ろのボタン押せるのかというと、ボタンやレイヤーなどにはタッチの優先度みたいなものが設定されていて、setTouchPriority()とかいうので設定できる。

ちなみにCCMenuは優先度-128が設定されていて(なんでか知らないけど小さいほうが優先度高い)、それはcocos2d-xのソースコードを読むとCCMenu.hに

enum {
    //* priority used by the menu for the event handler
    kCCMenuHandlerPriority = -128,
};

と書いてある。それでCCMenu.cppに

bool CCMenu::initWithArray(CCArray* pArrayOfItems)
{
    if (CCLayer::init())
    {
        setTouchPriority(kCCMenuHandlerPriority);
        setTouchMode(kCCTouchesOneByOne);
        setTouchEnabled(true);

//************* 略 *************
        
    return false;
}

と書いてある。

話を戻すと、つまりモーダルダイアログのpriorityを-128(kCCMenuHandlerPriorityのこと)より小さくすればいいということ。

だからModalLayer.hで

#define kModalLayerPriority kCCMenuHandlerPriority-1
#define kModalMenuPriority kCCMenuHandlerPriority-2

とかってして、それでModalLayer.cppで

bool SelectColorLayer::init()
{
    if (!CCLayer::init()) {
        return false;
    }
    
    // タップイベントを取得する
    this->setTouchPriority(kModalLayerPriority);
    this->setTouchEnabled(true);
    this->setTouchMode(kCCTouchesOneByOne);

//**************** 略 ****************

    CCMenu* menu = CCMenu::createWithArray(menuItems);
    menu->setTouchPriority(kModalMenuPriority);

//**************** 略 ****************

とかってする。.hのほうで2つあるのは、レイヤー自身のpriorityよりも、メニューのpriorityを更に小さくしないといけないから。

このコードでモーダルダイアログを出したり消したり繰り返してたら、ちょっとずつメモリ使用量が増えてきてて不穏な感じがしてる。個人的には removeFromParentAndCleanup(true); さえすればなんでもいいと思ってたけど、そうではないのかもしれない。