Prainブログ

ゲーム開発とかIT小話とかその他雑記のブログ

*

Cocos2d-x モーダルレイヤーの作り方

      2016/07/26

layer3

この記事ではCocos2d-xによるモーダルレイヤー実装のやり方について説明します。

 

 

スポンサーリンク

 

 

モーダルレイヤーとは

モーダルとは操作が完了するまで親への操作を受け付けなくさせるという意味の言葉です。つまりモーダルレイヤーとは「そのレイヤーが存在している間、そのレイヤーでしかタップ操作を受け付けないレイヤー」のことです。

 

それでは具体的にモーダルレイヤーの仕組みを見ていきましょう。

 

 

レイヤーを重ねてモーダルレイヤーの仕組みを理解する

レイヤーを重ねる

Cocos2d-xではレイヤーの上にスプライトを重ねて画面を構成します。このレイヤーは何枚も重ねることが可能です。

 

例えば、メインのゲーム画面上にメニューのような画面を表示させたい場合、「メニュー画面レイヤー」を作成して「メインのゲーム画面レイヤー」に追加することで、メニュー画面が作成できます。

layers

 

 

レイヤーを重ねることの不都合

ただし、単純にレイヤーを追加するだけでは不都合を引き起こす場合があります。両方のレイヤーにタップイベントリスナーが設定されている場合、メニュー画面だけを操作したいのに、メインのゲーム画面の操作も一緒に行ってしまうのです。

 

layer3

これを回避するには、メニュー画面レイヤーをモーダルレイヤーとして実装すれば良いのです。

 

それでは実際のモーダルレイヤーのコードを見ていきましょう。

 

 

モーダルレイヤーのコード

 

ModalLayer.h


#define kModalLayerPriority -1

#include <stdio.h>;
#include <cocos2d.h>;

class ModalLayer : public cocos2d::Layer{
public:

    virtual bool init();

    // touch
    virtual bool onTouchBegan(cocos2d::Touch* pTouch, cocos2d::Event* pEvent);
    virtual void onTouchEnded(cocos2d::Touch* pTouch, cocos2d::Event* pEvent);
    virtual void onTouchMoved(cocos2d::Touch* pTouch, cocos2d::Event* pEvent);
    
    
    CREATE_FUNC(ModalLayer);
    
};

 

 

 

ModalLayer.cpp

#include "ModalLayer.h"

using namespace cocos2d;

bool ModalLayer::init(){
    if(!Layer::init()){
        return false;
    }
  
    // event listener
    auto listener = EventListenerTouchOneByOne::create();
    listener->setSwallowTouches(true);
    listener->onTouchBegan = CC_CALLBACK_2(ModalLayer::onTouchBegan, this);
    listener->onTouchEnded = CC_CALLBACK_2(ModalLayer::onTouchEnded, this);
    listener->onTouchMoved = CC_CALLBACK_2(ModalLayer::onTouchMoved, this);
    
    this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
    this->getEventDispatcher()->setPriority(listener, kModalLayerPriority);
    
    return true;
}

bool ModalLayer::onTouchBegan(Touch* pTouch, Event* pEvent){
    return true;
}

void ModalLayer::onTouchMoved(Touch* pTouch, Event* pEvent){
    
}

void ModalLayer::onTouchEnded(Touch* pTouch, Event* pEvent){
    
}

 

 

モーダルレイヤー実現の仕組み

ポイントは以下の2点です。

・listener->setSwallowTouches(true)

優先度の高いイベントだけを実行するメソッドです。

今回の場合、「メニュー画面レイヤー」は「メインゲーム画面レイヤー」に対して前面ノードです。この時、この2つのレイヤーのイベントリスナーの優先度の関係は「メニュー画面レイヤー」>「メインゲーム画面レイヤー」となっています。※後から追加されたほうが前面ノード扱いとなります。

 

・onTouchBegan{return true;}

モーダルレイヤ側のonTouchBeganは処理の最後に必ずtrueを返す必要がありますtrueを返すことで初めてonSwallowTouches(true)の効果が得られます。もし、onTouchBeganがfalseを返した場合、下位レイヤーであるメインゲーム画面レイヤーまでタッチイベントが透過してしまいます。

 

 

このモーダルレイヤをメインゲーム画面レイヤーにaddChildしている間、モーダルレイヤのみの操作が可能になります。後はモーダルレイヤ上に実現したい処理を追加してください。

 

 

まとめ

モーダル化したいレイヤー側でsetSwallowTouches(true)とonTouchBegan{return true;}を記述することでモーダルレイヤーの実装が可能となります。

 

 

また、コードの丸暗記だけでなく、このような仕組みを知っておくことで、他の言語でも理解の応用が効くようになるのではないでしょうか。

 

 -

        

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

  関連記事

新しいファイル
ゲーム制作 Cocos2d-x関連 第8回 「より保守性のあるプログラムを目指して」

  何だこのタイトルは・・・ゲーム制作はどこに行ったの?   …

ゲーム制作 Cocos2d-x関連 最終回 「勝利演出、敗北演出の追加」

勝利演出、敗北演出を実装していきます。今回で最終回です!   &nbs …

アプリ名のローカライズ
Cocos2d-x アプリのアイコン名変更方法について iOS/Android

こんにちは。akiです。 この記事ではCocos2d-xにおけるアプリのアイコン …

マップイメージ
ゲーム制作 Cocos2d-x関連 第14回 「プレイヤー攻撃によるダメージ計算、ターン交代」

今回はプレイヤーのターン、敵のターンを交互に行うようにしていきます。また、それぞ …

シミュレータ
ゲーム制作 Cocos2d-x関連 第4回 「画面タッチに反応して画像を出そう」

画面を眺めててもゲームにはならないよ。画面タッチしたいんだけど!   …