天天看點

cocos2d-x學習筆記—自定義彈出層

           在玩遊戲的過程中,如果遊戲事件結束或者飛機英雄的生命值為0的時候,遊戲會彈出一個WIN或者Lose界面,并且是半透明的狀态。遊戲過程中,需要暫停遊戲的時候,點選暫停按鈕,彈出選項。。這些都是彈出層,它是加在GameScene這個節點上的。

引擎提供了CCLayerColor顔色布景層類,它可以直接加在Scene上,并且可以設定背景顔色的透明度。。。其構造方法如下:

CCLayerColor::create( ccc4(0, 0, 0, 180));
           

ccc4 是顔色清單,前三個是RGB顔色值,最後一個是透明度。

我們需要封裝的彈出層就要繼承CCLayerColor,在構造的時候方法和它相同。

          建立一個類PopLayer,先上代碼:

          PopLayer.h

#ifndef __POP_LAYER_H__
#define __POP_LAYER_H__

#include "cocos2d.h"
#include <vector>

USING_NS_CC;
using namespace std;

//自定義彈出層
class PopLayer : public CCLayerColor
{
public:
	static PopLayer* create(ccColor4B&);

	virtual bool PopInit();//初始化
public: //Touch事件
	virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
	virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
	virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
	virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);

	void onEnter();
	void onExit();

public:                                                                                             //初始化一個向量,存放所有注冊過Touch事件的按鈕
	vector<CCTouchDelegate*> m_vTouchObj;                                                       //Touch代理,用于注冊Touch
	CCTouchDelegate* m_pTouchDelegate;

public:
	//注冊Touch(因為彈出層的優先級我設定為最高,封閉Scene所有按鈕,那麼在彈出層上的按鈕就必須注冊按鈕事件才可以使用)
	void registerTouch(CCTouchDelegate*);
	//登出
	void unRegisterTouch(CCTouchDelegate*);
       //判斷是否添加監聽事件
	bool isContainTouch(CCTouchDelegate*);
};

#endif
           

            其中值得注意的就是按鈕事件的注冊。下面開始實作檔案 PopLayer.cpp

            (需要注意的我都在注釋标明)

#include "PopLayer.h"

//構造函數
PopLayer* PopLayer::create(ccColor4B& color)
{
	PopLayer* pop = new PopLayer();
	if (pop && pop->PopInit()&& pop->initWithColor(color))
	{
		pop->autorelease();//加入自動釋放池
		return pop;
	}
	//安全删除的宏
	CC_SAFE_DELETE(pop);
	return NULL;

}

bool PopLayer::PopInit()
{
	if (!CCLayerColor::init())
	{
		return false;
	}
	//代理指針初始化為空
	m_pTouchDelegate = NULL;

	return true;
}
void PopLayer::onEnter()
{
	CCLayerColor::onEnter();
	//注冊監聽事件,設定優先級為最高-128,第三個參數設定為true,表示吞噬事件,隻有向它注冊的才能夠點選
	CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,-128, true);  
}

void PopLayer::onExit()
{
	CCLayerColor::onExit();
	//登出監聽事件
	CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);  
}

//判斷注冊按鈕是否在向量内
bool PopLayer::isContainTouch(CCTouchDelegate* pTouch)
{
	for (vector<CCTouchDelegate*>::iterator it = m_vTouchObj.begin();it != m_vTouchObj.end();it++ )
	{
		if ((*it) == pTouch)
		{
			return true;
		}
	}
	return false;
}
void PopLayer::registerTouch(CCTouchDelegate* pTouch)
{
	//添加到注冊向量
	m_vTouchObj.push_back(pTouch);
	if (isContainTouch(pTouch))
	{
		//CCLOG("register");
	}

}
//登出
void PopLayer::unRegisterTouch(CCTouchDelegate* pTouch)
{
	for (vector<CCTouchDelegate*>::iterator it = m_vTouchObj.begin();it != m_vTouchObj.end();it++ )
	{
		if ((*it) == pTouch)
		{
		   //從向量移除
			m_vTouchObj.erase(it);
		}
	}
}

bool PopLayer::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
	m_pTouchDelegate = NULL;
	//點選Layer的時候周遊向量
	for (vector<CCTouchDelegate*>::iterator it = m_vTouchObj.begin();it != m_vTouchObj.end();it++ )
	{
		//對it解引用,*it即為注冊的按鈕,判斷*it按鈕是否有點選的操作
		if ((*it)->ccTouchBegan(pTouch,pEvent))
		{
			//若有,即指派給Touch代理指針,即可執行下面的幾個函數
			m_pTouchDelegate = (*it);
			break;
		}
	}
	return true;
}

void PopLayer::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
{
    //事件分發
	if (m_pTouchDelegate)
	{
		m_pTouchDelegate->ccTouchMoved(pTouch,pEvent);
	}
}
void PopLayer::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
	if (m_pTouchDelegate)
	{
		m_pTouchDelegate->ccTouchEnded(pTouch,pEvent);
	}
}
void PopLayer::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent)
{
	if (m_pTouchDelegate)
	{
		m_pTouchDelegate->ccTouchCancelled(pTouch,pEvent);
	}
}
           

                   一個簡單的彈出層就這樣,在使用的時候,我們隻需要繼承PopLayer這個類就行了。  比如我們需要一個pause按鈕,那麼我們的Pause就要繼承PopLayer就行。如下:

class PauseLayer : public PopLayer
           

 在PauseLayer的OnEnter與OnExit函數就要直接調用PopLayer,如下:

void PauseLayer::onExit()
{
	PopLayer::onExit();
	
}
void PauseLayer::onEnter()
{
	PopLayer::onEnter();	
}
           

     在Pause上肯定會有按鈕,别忘了向PopLayer注冊Touch事件,如下:

MyButton* goHome  = MyButton::create("btn.png",this,null,menu_selector(PauseLayer::GoHome));                                                                       //MyButton是自己定義的按鈕,可參見上一篇
	goHome     -> setPosition(ccp(270,640));
	goHome     -> setPosition(ccp(270,640));
	this->registerTouch(goHome); //注測按鈕事件,添上這一句才可以點選<span style="white-space:pre">		</span>
           

繼續閱讀