在玩游戏的过程中,如果游戏事件结束或者飞机英雄的生命值为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>