前端之家收集整理的这篇文章主要介绍了
Cocos2dx_可擦除Layer,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
- #ifndef __ERASABLELAYER_H__
- #define __ERASABLELAYER_H__
-
- #include "cocos2d.h"
-
- USING_NS_CC;
-
- // http://blog.csdn.net/linchaolong
- // 可擦除的Layer
- class ErasableLayer :public Layer
- {
- public:
- // 创建ErasableLayer
- //1.遮罩层
- //2.橡皮擦(可以是Sprite或者纹理的路径)
- static ErasableLayer* create(const char* layerPath,const char* erasaPath);
- static ErasableLayer* create(Node *layer,Sprite* erasa);
- static ErasableLayer* create(Node *layer,const char* erasaPath);
- static ErasableLayer* create(const char* layerPath,Sprite* erasa);
-
- // 还原
- void clear();
- // 是否可擦除
- void setErasable(bool);
-
- bool onTouchBegan(Touch* touch,Event *event);
- void onTouchesMoved(Touch* touch,Event *event);
- void onTouchEnded(Touch* touch,Event *event);
- protected:
- ErasableLayer();
- ~ErasableLayer();
-
- bool init(Node *layer,Sprite* erasa);
- void tick(float);
- private:
- Node* layer_;
- Sprite* erasa_;
- bool isErasable_;
- RenderTexture* rt_;
- };
-
- #endif
- #include "ErasableLayer.h"
-
- ErasableLayer::ErasableLayer() :isErasable_(true)
- {
- }
-
- ErasableLayer::~ErasableLayer()
- {
- CC_SAFE_RELEASE(layer_);
- CC_SAFE_RELEASE(erasa_);
- }
-
- ErasableLayer* ErasableLayer::create(const char* layerPath,const char* erasaPath)
- {
- CCSprite* layer = CCSprite::create(layerPath);
- CCSprite* erasa = CCSprite::create(erasaPath);
-
- ErasableLayer* ret = new ErasableLayer;
- if (ret->init(layer,erasa))
- {
- ret->autorelease();
- return ret;
- }
- delete ret;
- return nullptr;
- }
-
- ErasableLayer* ErasableLayer::create(Node* layer,Sprite* erasa)
- {
-
- ErasableLayer* ret = new ErasableLayer;
- if (ret->init(layer,const char* erasaPath)
- {
- CCSprite* erasa = CCSprite::create(erasaPath);
- ErasableLayer* ret = new ErasableLayer;
- if (ret->init(layer,erasa))
- {
- ret->autorelease();
- return ret;
- }
- delete ret;
- return nullptr;
- }
-
- ErasableLayer* ErasableLayer::create(const char* layerPath,Sprite* erasa)
- {
- CCSprite* layer = CCSprite::create(layerPath);
-
- ErasableLayer* ret = new ErasableLayer;
- if (ret->init(layer,erasa))
- {
- ret->autorelease();
- return ret;
- }
- delete ret;
- return nullptr;
- }
-
- bool ErasableLayer::init(Node *layer,Sprite* erasa)
- {
- if (!Layer::init())
- {
- return false;
- }
-
- layer_ = layer;
- erasa_ = erasa;
-
- layer_->retain();
- erasa_->retain();
-
- this->setContentSize(layer_->getContentSize());
-
- // 设置颜色混合模式
- BlendFunc erasaBf = { GL_ZERO,GL_ONE_MINUS_SRC_ALPHA }; //源因子:值为0,橡皮擦颜色为透明;目标因子:目标颜色透明度减去源颜色的透明度
- erasa_->setBlendFunc(erasaBf);
-
- auto size = layer_->getContentSize();
- rt_ = RenderTexture::create(size.width,size.height);
- rt_->setAnchorPoint(Vec2(0,0));
- rt_->setPosition(Vec2(size.width/2,size.height/2));
- this->addChild(rt_);
-
- clear();
-
- schedule(CC_SCHEDULE_SELECTOR(ErasableLayer::tick));
-
- // 触摸事件
- auto listener = EventListenerTouchOneByOne::create();
- listener->onTouchBegan = CC_CALLBACK_2(ErasableLayer::onTouchBegan,this);
- listener->onTouchMoved = CC_CALLBACK_2(ErasableLayer::onTouchesMoved,this);
- listener->onTouchEnded = CC_CALLBACK_2(ErasableLayer::onTouchEnded,this);
- _eventDispatcher->addEventListenerWithSceneGraPHPriority(listener,this);
- listener->setSwallowTouches(false);
-
- return true;
- }
-
- void ErasableLayer::tick(float)
- {
- if (!isErasable_)
- {
- return;
- }
-
- // 设置源颜色alpha值为最大值,目标颜色alpha值减去源颜色alpha值后就为0了,混合出来的效果就变透明了,这样就实现了橡皮擦效果了。
- erasa_->setOpacity(255);
-
- // 更新RenderTexture
- rt_->begin();
-
- // 绘制
- erasa_->visit();
-
- rt_->end();
- }
-
- void ErasableLayer::clear()
- {
- layer_->setAnchorPoint(Vec2(0,0));
- layer_->setPosition(Vec2(0,0));
-
- rt_->begin();
- layer_->visit();
- rt_->end();
- }
-
- void ErasableLayer::setErasable(bool flag)
- {
- isErasable_ = flag;
- }
-
- bool ErasableLayer::onTouchBegan(Touch* touch,Event *event)
- {
- erasa_->setPosition(this->convertToNodeSpace(touch->getLocation()));
- return true;
- }
-
- void ErasableLayer::onTouchesMoved(Touch* touch,Event *event)
- {
- erasa_->setPosition(this->convertToNodeSpace(touch->getLocation()));
- }
-
- void ErasableLayer::onTouchEnded(Touch* touch,Event *event)
- {
- erasa_->setPosition(this->convertToNodeSpace(touch->getLocation()));
- }
-