Cocos2d-x

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

投稿日:2016年7月25日 更新日:

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;}を記述することでモーダルレイヤーの実装が可能となります。

 

 

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

 

PrainGoogleAdSense

PrainGoogleAdSense

-Cocos2d-x
-

執筆者:


comment

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

関連記事

動作確認画像

Cocos2d-x アプリ起動画面(スプラッシュ画像)の変更方法について

この記事では、アプリの起動画面(スプラッシュ画像)の変更のやり方について説明します。     このスプラッシュ画像、どうやって変更するのか結構わかりづらいと思います。私もしばらくや …

cocos2dx

Cocos2d-x カスタムイベントを削除するタイミング

こんにちは、akiです。 この記事ではカスタムイベントを削除するタイミングについて説明します。   掲題の通り、カスタムイベントを登録した場合、不要になった際に明示的に削除してやる必要があり …

Cocos2d-x iOS アプリ名(アプリのアイコン名)のローカライズ方法

こんにちは。akiです。 この記事ではCocos2d-xでのアプリ名(アプリのアイコン名)のローカライズについて説明します。デバイスの環境に応じて一つのアプリのタイトル名を、日本語と英語でそれぞれ表示 …

cocos2dx

Cocos2d-x クライアント側の処理とデータ送信(Httpリクエスト)

この記事は「Cocos2d-x セーブデータをサーバに送信して保存する」の続きになります。   ・第1回 : サーバにデータを保存したい理由と全体の流れ ・第2回 : クライアント側の処理と …

アプリ 購入画面

SDKBoxを使ってアプリ内課金をするやり方 プログラム実装~実機テストまでの13の手順

この記事では、SDKBoxを利用したiOSアプリ内課金のプログラム実装から実機テストのやり方まで、一連の流れで説明します。     アプリ課金の実機テストを、実際の費用を掛けずに行 …