好记性不如铅笔头

C && C++, cocos2dx, 编程

cocos2dx学习笔记:水果忍者划痕效果

最近游戏中用到了划痕效果,就在网上google了一下,好多资源啊。作者找了一个,感觉还不错。在这里备份下。

参考【 http://blog.csdn.net/u012945598/article/details/17609281 】。

CONTENTS

代码备份:

.h文件:

#ifndef __RAZER_LAYER_H__
#define __RAZER_LAYER_H__

#include "cocos2d.h"

class RazerLayer : public cocos2d::CCLayer
{
public:
	const static int Tag = 139269181913;
	CREATE_FUNC(RazerLayer);
	virtual bool init();


	void draw();
	void drawLine();
	virtual void ccTouchesBegan(cocos2d::CCSet *pTouches,cocos2d::CCEvent *pEvent);
	virtual void ccTouchesMoved(cocos2d::CCSet *pTouches,cocos2d::CCEvent *pEvent);
	virtual void ccTouchesEnded(cocos2d::CCSet *pTouches,cocos2d::CCEvent *pEvent);
	std::list<cocos2d::CCPoint> pointList;
};

#endif // __RAZER_LAYER_H__

.m文件:

#include "RazerLayer.h"
USING_NS_CC;

bool RazerLayer::init()
{
	if ( !CCLayer::init() )
	{
		return false;
	}
	
	setTouchEnabled(true);
	return true;
}

void RazerLayer::draw()
{
    drawLine();
}
void RazerLayer::drawLine()
{
    int tickSubCount = 10;
    int pointListKeepCount = 500;
    
    for (int i=0; i<tickSubCount ; i++)
    {
        if (pointList.size() >0)
        {
            pointList.pop_front();
        }
        else
        {
            break;
        }
    }
    while (pointList.size() > pointListKeepCount)
    {
        pointList.pop_front();
    }
    
    float max_lineWidth = 5;
    float min_lineWidth = 1;
    int   alpha_min = 10;
    int   alpha_max =  200;
    
    int  R = 100;//arc4random()%255;
    int  G = 100;//arc4random()%255;
    int  B = 100;//arc4random()%255;
    
    int pointListCount = pointList.size();
    std::list <CCPoint>::iterator it =pointList.begin();
        
    float pointIndex = 0;
    for(;it!=pointList.end();it++)
    {
        int distanceToMiddle = fabs(pointIndex-pointListCount/2);
        float percent = 1.0-(float)distanceToMiddle/(float)(pointListCount/2.0);
        float lintWidth = min_lineWidth + max_lineWidth*percent;
        int alpha = alpha_min +alpha_max*percent;
        
        ccc4(R,G,B,alpha );
        ccPointSize(lintWidth);
        ccDrawPoint( *it );
        
        pointIndex++;
    }
}
void RazerLayer::ccTouchesBegan(CCSet *pTouches,CCEvent *pEvent)
{
    CCSetIterator it = pTouches->begin();
    CCTouch* touch = (CCTouch*)*it;
    CCPoint beginPoint = touch->getLocationInView();
    beginPoint = CCDirector::sharedDirector()->convertToGL(beginPoint);
// beginPoint 检测
    pointList.push_back(beginPoint);
}

void RazerLayer::ccTouchesMoved(CCSet *pTouches,CCEvent *pEvent)
{
    CCSetIterator it = pTouches->begin();
    CCTouch* touch = (CCTouch*)*it;
    
    CCPoint nextPoint = touch->getLocationInView( );
    nextPoint = CCDirector::sharedDirector()->convertToGL(nextPoint);
// nextPoint 检测
    CCPoint preMovePoint = touch->getPreviousLocationInView();
    preMovePoint = CCDirector::sharedDirector()->convertToGL(preMovePoint);
    
    float distance = ccpDistance(nextPoint, preMovePoint);
    if (distance > 1)
    {
        int d = (int)distance;
        for (int i =0; i < d; i++ )
        {
            float distanceX = nextPoint.x - preMovePoint.x;
            float distanceY = nextPoint.y - preMovePoint.y;
            
            float percent = i / distance;
            CCPoint newPoint;
            newPoint.x = preMovePoint.x + (distanceX * percent);
            newPoint.y = preMovePoint.y + (distanceY * percent); 
            
            pointList.push_back(newPoint);
        }
    }
}
void RazerLayer::ccTouchesEnded(CCSet *pTouches,CCEvent *pEvent)
{
    pointList.clear();
}

 分析:

代码原理比较清晰,在touchmove的回调方法中,获取两个手势点之间的所有的像素点,让后将存储起来,然后在每帧的绘制中根据每个点的位置设定不同的线宽,然后将这个点绘制出来。就形成了划痕效果。如果要在指定的范围内进行划痕处理,只要处理代码中的指定点即可。

发表评论

15 + 10 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据