#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())); }
原文地址:https://www.jb51.cc/cocos2dx/341483.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。