本文的新手引导适用于按照既定顺序让玩家完成按下按钮的新手引导方式,下方代码的环境为cocos2d-x 2.2.2版本
欢迎转载,请注明出处http://blog.youkuaiyun.com/yangjie314/article/details/24774673
几乎学习cocos2d-x的blog都有CCLayerColor 和CCClippingNode组合的新手引导教程,我写这篇blog目的一是备忘,二是对整个遮罩的实现进行一个简单的封装,方便以后使用,写的不是很完善,有什么建议,欢迎提出。
整个遮罩新手引导功能的大概思路说一下:
使用一个CCLayerColor作为CCClippingNode的底板,使用一个CCNode的子类,按钮、精灵作为裁剪板,将CCLayerColor裁剪,露出下方按钮,并且通过裁剪板CCNode的size来判断是否要吞噬触摸事件。整个教学层的裁剪点创建和改动,通过设置CCNode来控制。
下面代码,请看注释
头文件.h
/**
两个层 底层和遮罩层。
底层为游戏画面 使用几个按钮来表示
遮罩层为教学层 使用颜色层 通过遮罩来控制游戏流程 点击哪个按钮
*/
class ButtonLayer:public CCLayer{
public:
virtual bool init();
CREATE_FUNC(ButtonLayer);
void testCallback(CCObject* pSender);
};
class TeachLayer:public CCLayer
{
public:
virtual bool init();
CREATE_FUNC(TeachLayer);
//重载生命周期函数
virtual void onEnter();
//在onExit中取消触摸代理注册
virtual void onExit();
//设置触摸事件不往下传递
virtual void registerWithTouchDispatcher();
//重载触摸函数 CCSet *pTouches, CCEvent *pEvent
virtual bool ccTouchBegan(CCTouch* pTouche ,CCEvent* pEvent);
//设置裁剪精灵
void setClippingNode(CCNode* pNode);
CCSize winSize;
CCPoint origin ;
//用于画面遮罩
CCClippingNode* ClippingNode;
//用于触摸事件传递判断
CCRect clippingRect;
};
cpp:
bool TeachLayer::init(){
if (!CCLayer::init())
{
return false;
}
winSize = CCDirector::sharedDirector()->getWinSize();
origin = CCDirector::sharedDirector()->getVisibleOrigin();
//设置锚点忽略为false:锚点在0.5,0.5处 不设置或者为true默认锚点在0,0处
this->ignoreAnchorPointForPosition(true);
//设置可触摸
this->setTouchEnabled(true);
ClippingNode = NULL;
return true;
}
void TeachLayer::onEnter(){
CCLayer::onEnter();
}
//在onExit中取消触摸代理注册
void TeachLayer::onExit(){
CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
//先取消触摸代理
CCLayer::onExit();
}
void TeachLayer::registerWithTouchDispatcher(){
//设置触摸代理 吞掉事件
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,-128,true);
CCLayer::registerWithTouchDispatcher();
}
bool TeachLayer::ccTouchBegan(CCTouch* pTouche ,CCEvent* pEvent){
CCPoint point = pTouche->getLocation();
point = convertToWorldSpace(point);
//判断是否在裁剪矩形内
if (clippingRect.containsPoint(point))
{
CCLog("TeachLayer::ccTouchBegan");
//此处跳转下一个精灵的位置
return false;
}
return true;
}
void TeachLayer::setClippingNode(CCNode* pNode){
//CCPoint point = node->getPosition();
//this->addChild(pSprite);
CCRect rect = pNode->boundingBox();
rect.origin = convertToWorldSpace(rect.origin);
CCPoint point = convertToWorldSpace(pNode->getPosition());
clippingRect = CCRectMake(
rect.origin.x,
rect.origin.y,
rect.size.width,
rect.size.height);
//测试用,观察裁剪矩形是否正确
/*
//画出碰撞矩形
//创建drawnode对象
CCDrawNode* drawNode = CCDrawNode::create();
ccColor4F green = {0.5f, 0, 0, 0.5f};
//*注意 这几个点必须要围绕原点设置,否则坐标尼玛乱的一B
CCPoint points[4]={
ccp(-rect.size.width/2,-rect.size.height/2),
ccp(rect.size.width/2,-rect.size.height/2),
ccp(rect.size.width/2,rect.size.height/2),
ccp(-rect.size.width/2,rect.size.height/2),
};
//使用上面点点设置多边形
drawNode->drawPolygon(points, 4, green, 0, green);
//设置坐标
drawNode->setPosition(point);
this->addChild(drawNode);
*/
//设置切割
//如果第一次设置 就创建遮罩层
if (ClippingNode == NULL)
{
CCLayerColor* blackLayer = CCLayerColor::create(ccc4(0,0,0,200),winSize.width,winSize.height);
//把blackLayer设置为切割的底板
ClippingNode = CCClippingNode::create();
this->addChild(ClippingNode);
ClippingNode->setInverted(true);
//设置透明度阀值,意思是只把纹理中透明度大于阀值的像素点裁剪出来
//阀值的取值范围是0-1
ClippingNode->setAlphaThreshold(0.5f);
ClippingNode->addChild(blackLayer);
}
ClippingNode->setStencil(pNode);
//重置了裁剪节点必须重新绘制一下,否则找不到裁剪节点会报空指针
ClippingNode->draw();
}
欢迎转载,请注明出处 http://blog.youkuaiyun.com/yangjie314/article/details/24774673