cocos2d-x 中实现蒙板效果(新手引导常用)

来源:互联网 发布:矩阵音箱的连接方法 编辑:程序博客网 时间:2024/06/06 04:53

蒙板效果是新手引导中常用的效果,背景灰色透明,要点击的地方透明,这样来引导用户按照系统设定来点击。

最近项目中刚好需要用到蒙板效果,按照惯例搜索了一下看有没有现成的组件,找到几个发现都是用renderTexture来实现的,觉得有点复杂,就自己写了一个,最终效果还不错。

思路:

1、做一张蒙板图,四周灰色半透明,中间椭圆全透明;

2、将透明区域截成一张图,作为透明点击区,阴影部分截一个很小的图,用来制作蒙板阴影;

3、需要蒙板时,可以把蒙板分成5个区域,点击区域放透明精灵,其他1、2、3、4区域用阴影精灵来填充;

4、点击效果就判断是否点中透明精灵,点中就穿透下层,否则吃掉点击事件;


效果及原理如下图:



实现代码如下:


#ifndef HelloCpp_GuideLayer_h#define HelloCpp_GuideLayer_h#include "cocos2d.h"USING_NS_CC;class PlayerGuide:public CCLayer{public:    PlayerGuide();    virtual ~PlayerGuide();        CREATE_FUNC(PlayerGuide);    virtual bool init();    virtual void onEnter();    virtual void onExit();        virtual bool ccTouchBegan(CCTouch *touch, CCEvent *event);    virtual void ccTouchMoved(CCTouch *touch, CCEvent *event);    virtual void ccTouchEnded(CCTouch *touch, CCEvent *event);  public:    /**     *@brief设置蒙板亮点的大小和位置     *     *@param width 宽     *@param height 高     *@param point 亮点     */    void SetSizeAndPosition(float width,float height,CCPoint point);        CCSprite *m_pPointSprite; // 透明精灵,用于判断点击是否需要穿透    float m_fWidth;    float m_fHeight;};#endif

////  GuideLayer.cpp//  HelloCpp////  ////#include "GuideLayer.h"PlayerGuide::PlayerGuide(){    m_fWidth = 0.0f;    m_fHeight = 0.0f;}PlayerGuide::~PlayerGuide(){    }bool PlayerGuide::init(){    if (!CCLayer::init()) {        return false;    }        return true;}void PlayerGuide::onEnter(){    // 监听点击事件    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate((CCTouchDelegate *)this, -100001, true);    CCLayer::onEnter();}void PlayerGuide::onExit(){    // 移除监听事件    CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate((CCTouchDelegate *)this);    CCLayer::onExit();}void PlayerGuide::SetSizeAndPosition(float width,float height, CCPoint point){    removeAllChildrenWithCleanup(true);    // 根据传入的亮点和大小来确定透视精灵的大小和位置,把整个层其他地方分成4部分,设置为背景的sprite    if (width != 0 && height != 0) {        m_fWidth = width;        m_fHeight = height;                CCSize winSize = CCDirector::sharedDirector()->getWinSize();        float fFactor = 1;        m_pPointSprite = CCSprite::create("透明点击图");        m_pPointSprite->setPosition(point);        if(width/m_pPointSprite->getContentSize().width > height/m_pPointSprite->getContentSize().height)            fFactor = height/m_pPointSprite->getContentSize().height;        else            fFactor = width/m_pPointSprite->getContentSize().width;        m_pPointSprite->setScale(fFactor);                    addChild(m_pPointSprite, 1);                        CCSprite *pSprite1 = CCSprite::create("半透明蒙板图");        pSprite1->setScaleX((point.x-m_pPointSprite->getContentSize().width*m_pPointSprite->getScale()/2)/pSprite1->getContentSize().width);        pSprite1->setScaleY(winSize.height/pSprite1->getContentSize().height);        pSprite1->setPosition(ccp(pSprite1->getContentSize().width*pSprite1->getScaleX()/2, winSize.height/2));        addChild(pSprite1, 1);                        CCSprite *pSprite2 = CCSprite::create("半透明蒙板图");        pSprite2->setScaleX((m_pPointSprite->getContentSize().width*m_pPointSprite->getScale())/pSprite2->getContentSize().width);        pSprite2->setScaleY((winSize.height-point.y-m_pPointSprite->getContentSize().height*m_pPointSprite->getScale()/2)/pSprite2->getContentSize().height);        pSprite2->setPosition(ccp(point.x, winSize.height-pSprite2->getContentSize().height*pSprite2->getScaleY()/2));        addChild(pSprite2, 1);        CCSprite *pSprite3 = CCSprite::create("半透明蒙板图");        pSprite3->setScaleX((m_pPointSprite->getContentSize().width*m_pPointSprite->getScale())/pSprite3->getContentSize().width);        pSprite3->setScaleY((point.y-m_pPointSprite->getContentSize().height*m_pPointSprite->getScale()/2)/pSprite3->getContentSize().height);        pSprite3->setPosition(ccp(point.x, pSprite3->getContentSize().height*pSprite3->getScaleY()/2));        addChild(pSprite3, 1);                CCSprite *pSprite4 = CCSprite::create("半透明蒙板图");        pSprite4->setScaleX((winSize.width-point.x-m_pPointSprite->getContentSize().width*m_pPointSprite->getScale()/2)/pSprite4->getContentSize().width);        pSprite4->setScaleY(winSize.height/pSprite4->getContentSize().height);        pSprite4->setPosition(ccp(winSize.width-pSprite4->getContentSize().width*pSprite4->getScaleX()/2, winSize.height/2));        addChild(pSprite4, 1);    }}bool PlayerGuide::ccTouchBegan(cocos2d::CCTouch *touch, cocos2d::CCEvent *event){    CCPoint touchpoint = touch->getLocationInView();    touchpoint = CCDirector::sharedDirector()->convertToGL(touchpoint);        if (m_fWidth != 0 && m_fHeight != 0) {        //如果点击高亮区域,则响应下层的区域        CCRect rect = m_pPointSprite->boundingBox();        if (rect.containsPoint( touchpoint)) {            return false;        }                        return true;    }}void PlayerGuide::ccTouchMoved(cocos2d::CCTouch *touch, cocos2d::CCEvent *event){    }void PlayerGuide::ccTouchEnded(cocos2d::CCTouch *touch, cocos2d::CCEvent *event){     }