加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Cocos2dx_可擦除Layer

发布时间:2020-12-14 16:31:05 所属栏目:百科 来源:网络整理
导读:#ifndef __ERASABLELAYER_H__#define __ERASABLELAYER_H__#include "cocos2d.h"USING_NS_CC;// http://blog.csdn.net/linchaolong// 可擦除的Layerclass ErasableLayer :public Layer{public:// 创建ErasableLayer//1.遮罩层//2.橡皮擦(可以是Sprite或者纹
#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()));
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读