如图:
2.在遮罩添加解说UI及相应动画
如图:
为了实现遮罩功能,我们选择一个模板切割图片的节点-- CCClipingNode.它的继承关系如下:
所以CCClipingNode裁剪节点在组成上=底板+模版,而在显示上=底板+模版.
如图:
2. CCClipingNode API:
注:
getStencil:返回一个节点对象,这个对象就是之前提到的“裁减模板”。
setStencil:设置“裁减模板”。
getAlphaThreshold::这种裁减是可以改变裁减的透明度的,修改这个透明度就是通过设置这个阈值。
setAlphaThreshold:获得这个透明度阈值。
isInverted:之前说过的剪刀剪形状的例子,剪完形状以后,是显示被剪掉的部分,还是显示剩余的部分呢,默认isInverted值是false,是显示被剪掉的部分,设置为true则是显示剩余的部分。这个函数获得这个值。
setInverted:设置isInverted值。
3.CCDrawNode
为了绘制相应图形,使用CCDrawNode类,它的继承关系如下:
4. CCDrawNodeAPI:
注释:
drawDot:绘制点,参数给出坐标位置。
drawSegment:绘制片断,给出起始点,结束点,半径等参数。
drawPolygon:绘制矩形,可以分别给出填充颜色和边框颜色,还可以设置边框宽度。
1)绘制矩形区域:
RectangleLayer.h
#ifndef __RECTANGLELAYER_LAYER__ #define __RECTANGLELAYER_LAYER__ #include "cocos2d.h" USING_NS_CC; class RectangleLayer:public cocos2d::CCLayer { public: static RectangleLayer* create(const char *pszFileName,CCPoint pos,CCRect rect, int pType); virtual bool initWithFile(const char *pszFilename,CCPoint pos,CCRect rect, int pType); virtual bool init(); RectangleLayer(void); virtual ~RectangleLayer(void); virtual void registerWithTouchDispatcher(); void refreshRect(CCPoint pos,CCRect rect, int pType); bool ccTouchBegan( CCTouch* pTouch, CCEvent* pEvent ); CCString* getGuideMsgByType(int pType); void setGuideVisible(bool isVisible); CREATE_FUNC(RectangleLayer); private: CCSprite* mCircle; CCSprite* pHand; CCDrawNode *mStencil; CCRect m_obRect; CCDictionary* m_pMsgDictionary; }; #endifRectangleLayer.cpp
#include "RectangleLayer.h" USING_NS_CC; RectangleLayer::RectangleLayer() { } RectangleLayer::~RectangleLayer() { } RectangleLayer* RectangleLayer::create(const char *pszFileName,CCPoint pos,CCRect rect, int pType) { RectangleLayer *pobGuideLayer = new RectangleLayer(); if (pobGuideLayer && pobGuideLayer->initWithFile(pszFileName,pos,rect,pType)) { pobGuideLayer->autorelease(); return pobGuideLayer; } CC_SAFE_DELETE(pobGuideLayer); return NULL; } bool RectangleLayer::init() { if (!CCLayer::init()) { return false; } return true; } bool RectangleLayer::initWithFile(const char *pszFileName,CCPoint pos,CCRect rect, int pType) { if (!CCLayer::init()) { return false; } m_obRect = rect; setTouchEnabled(true); //创建cliper对象 CCClippingNode* pClip = CCClippingNode::create(); pClip->setInverted(true); addChild(pClip); mCircle=CCSprite::create(pszFileName); mCircle->setPosition(pos); mCircle->setAnchorPoint(ccp(-0.5f,0.5f)); mCircle->runAction(CCRepeatForever::create(CCSequence::createWithTwoActions(CCScaleBy::create(0.05f, 0.95f), CCScaleTo::create(0.125f, 1)))); addChild(mCircle); //加入灰色的底板 CCLayerColor* pColor = CCLayerColor::create(ccc4(0,0,0,180)); pClip->addChild(pColor); mStencil = CCDrawNode::create(); static ccColor4F green = {0,1,0,1}; float width = m_obRect.size.width; float height = m_obRect.size.height; float x = pos.x; float y = pos.y; static CCPoint rect1[4] = {ccp(0,height),ccp(width,height),ccp(width,0),ccp(0,0)}; mStencil->drawPolygon(rect1,4,green,0,green); mStencil->setPosition(pos); pClip->setStencil(mStencil); mStencil->runAction(CCRepeatForever::create(CCSequence::createWithTwoActions(CCScaleBy::create(0.05f, 0.95f), CCScaleTo::create(0.125f, 1)))); return true; } void RectangleLayer::registerWithTouchDispatcher() { //使用-128和CCMenu优先级相同,并且吞掉事件true// CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -130, true); CCLayer::registerWithTouchDispatcher(); } void RectangleLayer::refreshRect(CCPoint pos,CCRect rect, int pType) { float fRadius=mCircle->getContentSize().width; float scale = rect.size.width/fRadius; mCircle->setScale(scale); mCircle->setPosition(pos); mStencil->setPosition(pos); mStencil->setScale(scale); //设置触碰区域 float x = pos.x; float y = pos.y; float width = mCircle->getContentSize().width *scale; float height = mCircle->getContentSize().height * scale; m_obRect = CCRectMake(x, y, width, height); } bool RectangleLayer::ccTouchBegan( CCTouch* pTouch, CCEvent* pEvent ) { //得到触摸位置 CCPoint touchPoint = pTouch->getLocation(); //判断点是否在矩形 CCRect m_obRect1 = m_obRect中 if (m_obRect.containsPoint(touchPoint)) { //CCPoint pos = ccp(m_obRect.getMidX(),m_obRect.getMidY()); CCPoint pos = pTouch->getLocation(); //这里要转化为UI坐标系(左上角为0,0点) pos = CCDirector::sharedDirector()->convertToUI(pos); //设置触摸信息 pTouch->setTouchInfo(pTouch->getID(),pos.x,pos.y); CCLog("helloWorld"); //removeFromParent(); //触发后移除 return false; } return true; } //是否显示 void RectangleLayer::setGuideVisible(bool isVisible) { this->setVisible(isVisible); setTouchEnabled(isVisible); } //获取文字信息 CCString* RectangleLayer::getGuideMsgByType(int pType) { char typeStr[10]; sprintf(typeStr, "%d", pType); CCString* msg = (CCString*)m_pMsgDictionary->objectForKey(typeStr); return msg; }在HelloWorldScene.cpp 的init方法添加代码:
CCRect m_obRect=CCRectMake( 100, 160, 100, 100); CCPoint dstPoint = mCircle->getPosition(); CCPoint newPoint = ccp(100,160); RectangleLayer *myGuideLayer = RectangleLayer::create("hand.png",newPoint,m_obRect,0); //myGuideLayer->refreshRect(newPoint1,m_obRect1, 0); addChild(myGuideLayer);运行效果:
2)绘制圆形区域:
因实现原理和以上类似,只需要更改下代码即可:
RoundnessLayer.cpp
#include "RoundnessLayer.h" USING_NS_CC; RoundnessLayer::RoundnessLayer() { } RoundnessLayer::~RoundnessLayer() { } RoundnessLayer* RoundnessLayer::create(const char *pszFileName,CCPoint pos,CCRect rect, int pType) { RoundnessLayer *pobGuideLayer = new RoundnessLayer(); if (pobGuideLayer && pobGuideLayer->initWithFile(pszFileName,pos,rect,pType)) { pobGuideLayer->autorelease(); return pobGuideLayer; } CC_SAFE_DELETE(pobGuideLayer); return NULL; } bool RoundnessLayer::init() { if (!CCLayer::init()) { return false; } return true; } bool RoundnessLayer::initWithFile(const char *pszFileName,CCPoint pos,CCRect rect, int pType) { if (!CCLayer::init()) { return false; } m_obRect = rect; setTouchEnabled(true); CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); //创建裁减节点类 CCClippingNode* pClip = CCClippingNode::create(); pClip->setInverted(true); addChild(pClip); //遮罩层 CCLayerColor* pColor = CCLayerColor::create(ccc4(0,0,0,180)); pClip->addChild(pColor); mCircle=CCSprite::create(pszFileName); float fRadius = rect.size.width/2; //圆的半径 mCircle->setPosition(pos); mCircle->setAnchorPoint(ccp(-0.5f,0.5f)); mCircle->runAction(CCRepeatForever::create(CCSequence::createWithTwoActions(CCScaleBy::create(0.05f, 0.95f), CCScaleTo::create(0.125f, 1)))); addChild(mCircle); //绘制圆形区域 static ccColor4F green = {1, 1, 1, 1}; //顶点颜色,这里我们没有实质上没有绘制,所以看不出颜色 const int nCount=100; //圆形其实可以看做正多边形,我们这里用正100边型来模拟园 const float coef = 2.0f * (float)M_PI/nCount; //计算每两个相邻顶点与中心的夹角 static CCPoint circle[nCount]; //顶点数组 for(unsigned int i = 0;i <nCount; i++) { float rads = i*coef; //弧度 circle[i].x = fRadius * cosf(rads); //对应顶点的x circle[i].y = fRadius * sinf(rads); //对应顶点的y } //绘制矩形,可以分别给出填充颜色和边框颜色,还可以设置边框宽度 mStencil=CCDrawNode::create(); mStencil->drawPolygon(circle, nCount, green, 0, green); //绘制这个多边形! //动起来 mStencil->runAction(CCRepeatForever::create(CCSequence::createWithTwoActions(CCScaleBy::create(0.05f, 0.95f), CCScaleTo::create(0.125f, 1)))); float x = pos.x + rect.size.width/2; float y = pos.y + rect.size.width/2; mStencil->setPosition(ccp(x,y)); //设这模板 pClip->setStencil(mStencil); //CCLayerColor* layer1 = CCLayerColor::create(ccc4(192, 0, 0, 25), rect.size.width, rect.size.height); //layer1->setPosition(pos); //addChild(layer1); return true; } void RoundnessLayer::registerWithTouchDispatcher() { //使用-128和CCMenu优先级相同,并且吞掉事件true// CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -130, true); CCLayer::registerWithTouchDispatcher(); } void RoundnessLayer::refreshRect(CCPoint pos,CCRect rect, int pType) { //调整大小 float fRadius=mCircle->getContentSize().width*0.5; float scale = rect.size.width/fRadius; //调整光亮区坐标 float x = pos.x + rect.size.width/2; float y = pos.y + rect.size.width/2; mCircle->setScale(scale); mCircle->setPosition(pos); mStencil->setPosition(ccp(x, y)); mStencil->setScale(scale); //设置触碰区域 float rectX = pos.x; float rectY = pos.y; float width = mCircle->getContentSize().width *scale; float height = mCircle->getContentSize().height * scale; m_obRect = CCRectMake(rectX, rectY, width, height); } bool RoundnessLayer::ccTouchBegan( CCTouch* pTouch, CCEvent* pEvent ) { //得到触摸位置 CCPoint touchPoint = pTouch->getLocation(); //判断点是否在矩形 CCRect m_obRect1 = m_obRect中 if (m_obRect.containsPoint(touchPoint)) { CCPoint pos = ccp(m_obRect.getMidX(),m_obRect.getMidY()); //这里要转化为UI坐标系(左上角为0,0点) pos = CCDirector::sharedDirector()->convertToUI(pos); //设置触摸信息 pTouch->setTouchInfo(pTouch->getID(),pos.x,pos.y); CCLog("helloWorld"); return false; } CCLog("no"); return true; } void RoundnessLayer::setGuideVisible(bool isVisible) { this->setVisible(isVisible); setTouchEnabled(isVisible); } CCString* RoundnessLayer::getGuideMsgByType(int pType) { char typeStr[10]; sprintf(typeStr, "%d", pType); CCString* msg = (CCString*)m_pMsgDictionary->objectForKey(typeStr); return msg; }运行效果:
有关解说UI及动画的话,就按自己的项目要求贴到遮罩层上,就OK了。
若想让真机正常显示,稍微更改接口参数:
for iOS: in AppController replace the gl-view creation with:
EAGLView *__glView = [EAGLView viewWithFrame: [window bounds] pixelFormat: kEAGLColorFormatRGBA8 depthFormat: GL_DEPTH24_STENCIL8_OES preserveBackbuffer: NO sharegroup: nil multiSampling: NO numberOfSamples: 0];
public Cocos2dxGLSurfaceView onCreateView() { Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this); glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8); return glSurfaceView; }
引用博客:
http://bbs.9ria.com/thread-182383-1-1.html
http://blog.csdn.net/jackystudio/article/details/17160973