这几天在研究《Hi Seal》划地的效果,无意间搜到了http://www.cocoachina.com/bbs/read.php?tid=12505&page=1上妄撮的帖子,之后又搜了一些,形成现在的Demo。
1110
现在的功能:
1)擦除图片
2)提供了一个计算擦除百分比的方法
未实现的功能:
1)Shake复原 (似乎cocos2dx不支持)
2)原版妄撮里,纸张撕裂的边缘效果
3)似乎还有很多……
废话不多说,直接上关键代码:
头文件:(头文件里写USING_NS_CC不知道是不是个坏习惯,求教)
#include "cocos2d.h"
USING_NS_CC;
class ScratchSprite : public CCLayer
{
public:
static ScratchSprite *create(const char *scratchSprite, const char *blendSprite);
bool initWithScratchAndBlendSprites(const char *scratchSprite, const char *blendSprite);
virtual void registerWithTouchDispatcher(void);
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);
private:
void resetRenderTexture();
void tick(float dt);
float alphaPercent();
private:
CCSprite *_scratchSprite;
CCRenderTexture *_renderTexture;
CCSprite *_blendSprite;
};
实现:
#define BLEND_INIT_POSITION ccp(10000, 10000)
ScratchSprite *ScratchSprite::create(const char *scratchSprite, const char *blendSprite)
{
ScratchSprite *scratch = new ScratchSprite();
if ( scratch && scratch->initWithScratchAndBlendSprites(scratchSprite, blendSprite) ) {
scratch->autorelease();
return scratch;
} else {
delete scratch;
scratch = NULL;
return NULL;
}
}
bool ScratchSprite::initWithScratchAndBlendSprites(const char *scratchSprite, const char *blendSprite)
{
CCSize spriteSize = CCSizeZero;
_scratchSprite = CCSprite::create(scratchSprite);
spriteSize = _scratchSprite->getContentSize();
setContentSize(spriteSize);
_scratchSprite->setPosition(ccp(spriteSize.width/2, spriteSize.height/2));
_scratchSprite->retain();
_blendSprite = CCSprite::create(blendSprite);
_blendSprite->setPosition(BLEND_INIT_POSITION);
_blendSprite->setBlendFunc((ccBlendFunc){GL_ZERO, GL_ONE_MINUS_SRC_ALPHA});
_blendSprite->retain();
_renderTexture = CCRenderTexture::create(spriteSize.width, spriteSize.height);
_renderTexture->setPosition(_scratchSprite->getPosition());
_renderTexture->getSprite()->setBlendFunc((ccBlendFunc){GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA});
addChild(_renderTexture);
resetRenderTexture();
schedule(schedule_selector(ScratchSprite::tick));
setTouchEnabled(true);
return true;
}
void ScratchSprite::resetRenderTexture()
{
_renderTexture->begin();
_scratchSprite->visit();
_renderTexture->end();
}
void ScratchSprite::tick(float dt)
{
_renderTexture->begin();
glColorMask(false, false, false, true);
_blendSprite->visit();
glColorMask(true, true, true, true);
_renderTexture->end();
}
float ScratchSprite::alphaPercent()
{
int width = getContentSize().width;
int height = getContentSize().height;
int numberOfTransparent = 0;
int numberOfPixels = width * height;
int bytesPerRow = width * 4;
GLubyte *buffer = new GLubyte;
if ( ! buffer ) {
CCLOG("cocos2dx: no enough space!");
delete ] buffer;
return 0.0f;
}
_renderTexture->begin();
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
_renderTexture->end();
int x, y;
for ( x = 0; x < width; ++x ) {
for ( y = 0; y < height; ++y ) {
GLubyte alpha = buffer;
if ( alpha == 0 ) {
numberOfTransparent++;
}
}
}
delete ] buffer;
return 100.0f * numberOfTransparent / numberOfPixels;
}
void ScratchSprite::registerWithTouchDispatcher()
{
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
}
bool ScratchSprite::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
CCPoint location = this->convertTouchToNodeSpace(pTouch);
if ( ! this->boundingBox().containsPoint(location) ) {
return false;
}
_blendSprite->setPosition(location);
return true;
}
void ScratchSprite::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
{
CCPoint location = this->convertTouchToNodeSpace(pTouch);
if ( this->boundingBox().containsPoint(location) ) {
_blendSprite->setPosition(location);
}
}
void ScratchSprite::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
_blendSprite->setPosition(BLEND_INIT_POSITION);
CCLOG("Transparent Percentage: %.0f", alphaPercent());
}
void ScratchSprite::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent)
{
_blendSprite->setPosition(BLEND_INIT_POSITION);
CCLOG("Transparent Percentage: %.0f", alphaPercent());
}
高手请指点一下各种不错(逻辑、代码规范、结构什么的)