在玩遊戲的過程中,如果遊戲事件結束或者飛機英雄的生命值為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>