前端之家收集整理的这篇文章主要介绍了
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()));
}