Luaでのモーダルレイヤー
先日待望のCococs2d-xの日本語の書籍が発売されました。
その中でモーダルレイヤーの作り方が書いてあり、本のままLuaでやろうとしてちょっと悩んだので書いておきます。
モーダルレイヤー
ゲーム画面の上に確認画面等を表示したとき、確認画面のボタンやタッチだけ反応して、ゲーム画面は反応してほしくない! とうことがよくあると思います。
cocos2d-xでどやってそれを実装するかですが、
- ゲーム画面のボタンやタッチの反応をON/OFFする。
- ゲーム画面にボタンやタッチのイベントを通知しない。
等があると思います。
1.は簡単に思いつく方法でメニューボタンやタッチをEnabled(false)するだけでOKですが、メニューの数だけ用意する必要があり大変です。
2.は"タッチの優先度"を利用した方法です。メニューよりもタッチ優先度の高いレイヤーを用意して全てのタッチイベントを拾い、それ以下にはタッチ処理をさせないようにします。
いままで1.の方法でやっていたのですが、2.の方法を本で知ったので試してみました。
Luaでのモーダルレイヤーの作り方
まず、本で紹介されているC++での実装方法
CCLayerを継承したModalLayerクラス内のinit()で優先度を設定し、ccTouchBeganでtrueを返すことで、それ以下へタッチイベントを渡さないようにしています。
//kCCMenuHandlerPriority = -128 CCMenuのデフォルトの優先度 bool ModalLayer::init() { ~省略~ this->setTouchPriority( kCCMenuHandlerPriority - 1) //優先度をCCMenuより高く this->setTouchEnabled(true); //タッチを有効化 this->setTouchMode(kCCTouchesOneByOne); //シングルタッチで拾う ~~~~ } bool ModalLayer::ccTouchBegan( CCTouch* touch, CCEvent* event) { //モーダルレイヤーですべてのタッチイベントを拾う return true; }
これをLuaでも作ってみますが注意点が2点。
LuaからもCCLayer:setTouchPriority()を使用できますが、これは動作しません!?
setTouchPriority() で優先度を設定しても実際に反映されず、デフォルトの優先度0になってしまいます。
ついでにsetTouchMode()ですが、これも動作しません!?
では、どうするかというと、
CCLayer:registerScriptTouchHandler(nHandler, bIsMultiTouches, nPriority, bSwallowsTouches)
を使用します。
Luaでのモーダルレイヤーは以下のようになります。
function ModalLayer:init() ~省略~ self:registerScriptTouchHandler( function(...) return self:onTouch(...) end, --タッチイベントハンドラーを指定 false, --シングルタッチで拾う kCCMenuHandlerPriority -1, --優先度をCCMenuより高く true --タッチイベントを止めるか ) ~~~~ end function ModalLayer:onTouch( eventType, x, y) --モーダルレイヤーですべてのタッチイベントを拾う return true end
Luaではハンドラーを登録すると共に、シングルorマルチタッチ、タッチの優先度、イベントを止めるかの設定をします。
注意するのは、4番目の引数 SwallowsTouches = trueにしただけでは、イベントを止められないというところです。C++と同じようにタッチイベントを処理するonTouch内で return trueをする必要があります。