如圖:
實現思路:
2.在遮罩添加解說UI及相應動畫
如圖:
具體實現:
爲了實現遮罩功能,我們選擇一個模板切割圖片的節點-- CCClipingNode.它的繼承關係如下:
- 首先它是一個節點,繼承於CCNode,所以它可以像普通節點一樣放入CCLayer,CCScene,CCNode中。
- 作爲節點,它就可以用作容器,承載其他節點和精靈。我把它叫底板。
- 如果想要對一個節點進行裁剪,那需要給出裁剪的部分,這個裁剪區域,我把它叫模版。
所以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;
};
#endif
RectangleLayer.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];
for Android: in game activity:
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