微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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()));
}

原文地址:https://www.jb51.cc/cocos2dx/341483.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐