您的位置:首页 > Web前端 > Node.js

CCMotionStreak(ccnode子类 可实现拖尾效果 需要设置--- 消隐动画时长,拖尾条带相邻顶点间的最小距离,拖尾条带的宽度,顶点颜色,纹理)

2014-05-22 09:38 411 查看
例子:

以下示例出自tests项目中的MotionStreakTest文件夹下的MotionStreakTest.cpp文件,其中的MotionStreakTest2类如代码清单3-43所示。

代码清单3-43 定义CCMotionStreak对象

void MotionStreakTest2::onEnter()

{

MotionStreakTest::onEnter();

setTouchEnabled(true);

CCSize s = CCDirector::sharedDirector()->getWinSize();

streak = CCMotionStreak::create(3, 3, 64, ccWHITE, s_streak );

addChild(streak);

streak->setPosition( CCPointMake(s.width/2, s.height/2) );

}

void MotionStreakTest2::ccTouchesMoved(CCSet* touches, CCEvent* event)

{

CCSetIterator it = touches->begin();

CCTouch* touch = (CCTouch*)(*it);

CCPoint touchLocation = touch->locationInView();

touchLocation = CCDirector::sharedDirector()->convertToGL( touchLocation );

streak->setPosition( touchLocation );

}

以上代码使用create函数创建CCMotionStreak对象,每次调用setPosition函数重新设置对象位置时,“影子”将被创建并且慢慢渐隐,

#ifndef __CCMOTION_STREAK_H__
#define __CCMOTION_STREAK_H__

#include "CCProtocols.h"
#include "textures/CCTexture2D.h"
#include "ccTypes.h"
#include "base_nodes/CCNode.h"
#ifdef EMSCRIPTEN
#include "base_nodes/CCGLBufferedNode.h"
#endif // EMSCRIPTEN

NS_CC_BEGIN

/**
* @addtogroup misc_nodes
* @{
*/

/** MotionStreak.
Creates a trailing path.
*/
class CC_DLL CCMotionStreak : public CCNodeRGBA, public CCTextureProtocol
#ifdef EMSCRIPTEN
, public CCGLBufferedNode
#endif // EMSCRIPTEN
{
public:
CCMotionStreak();
virtual ~CCMotionStreak();

// 创建一个拖尾效果,参一为消隐动画时长,参二为拖尾条带相邻顶点间的最小距离,参三为拖尾条带的宽度,参四为顶点颜色值,参五为所使用的纹理图片。
static CCMotionStreak*
create(float fade, float minSeg, float stroke, ccColor3B color, const char* path);
//同上 参五为所使用的纹理对象指针。
static CCMotionStreak*
create(float fade, float minSeg, float stroke, ccColor3B color, CCTexture2D* texture);
bool
initWithFade(float fade, float minSeg, float stroke, ccColor3B color, const char* path);

{
CCAssert(path != NULL, "Invalid filename");
CCTexture2D *texture = CCTextureCache::sharedTextureCache()->addImage(path);
return initWithFade(fade, minSeg, stroke, color, texture);
}
bool
initWithFade(float fade, float minSeg, float stroke, ccColor3B color, CCTexture2D* texture);

{
CCNode::setPosition(CCPointZero);
setAnchorPoint(CCPointZero);
ignoreAnchorPointForPosition(true);
m_bStartingPositionInitialized = false;

m_tPositionR = CCPointZero;
m_bFastMode = true;
m_fMinSeg = (minSeg == -1.0f) ? stroke/5.0f : minSeg;
m_fMinSeg *= m_fMinSeg;

m_fStroke = stroke;
m_fFadeDelta = 1.0f/fade;

m_uMaxPoints = (int)(fade*60.0f)+2;
m_uNuPoints = 0;
m_pPointState = (float *)malloc(sizeof(float) * m_uMaxPoints);
m_pPointVertexes = (CCPoint*)malloc(sizeof(CCPoint) * m_uMaxPoints);

m_pVertices = (ccVertex2F*)malloc(sizeof(ccVertex2F) * m_uMaxPoints * 2);
m_pTexCoords = (ccTex2F*)malloc(sizeof(ccTex2F) * m_uMaxPoints * 2);
m_pColorPointer = (GLubyte*)malloc(sizeof(GLubyte) * m_uMaxPoints * 2 * 4);

// Set blend mode
m_tBlendFunc.src = GL_SRC_ALPHA;
m_tBlendFunc.dst = GL_ONE_MINUS_SRC_ALPHA;

// shader program
setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureColor));

setTexture(texture);
setColor(color);
scheduleUpdate();

return true;
}
/** color used for the tint */
void
tintWithColor(ccColor3B colors);

{
setColor(colors);

// Fast assignation
for(unsigned int i = 0; i<m_uNuPoints*2; i++)
{
*((ccColor3B*) (m_pColorPointer+i*4)) = colors;
}
}

//删除所有的条带段
void reset();

virtual void setPosition(const CCPoint& position);

{
m_bStartingPositionInitialized = true;
m_tPositionR = position;
}

virtual void
draw();

{
if(m_uNuPoints <= 1)
return;

CC_NODE_DRAW_SETUP();

ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex );
ccGLBlendFunc( m_tBlendFunc.src, m_tBlendFunc.dst );

ccGLBindTexture2D( m_pTexture->getName() );

#ifdef EMSCRIPTEN
// Size calculations from ::initWithFade
setGLBufferData(m_pVertices, (sizeof(ccVertex2F) * m_uMaxPoints * 2), 0);
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, 0);

setGLBufferData(m_pTexCoords, (sizeof(ccTex2F) * m_uMaxPoints * 2), 1);
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, 0, 0);

setGLBufferData(m_pColorPointer, (sizeof(GLubyte) * m_uMaxPoints * 2 * 4), 2);
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
#else
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, m_pVertices);
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, 0, m_pTexCoords);
glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, m_pColorPointer);
#endif // EMSCRIPTEN

glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)m_uNuPoints*2);

CC_INCREMENT_GL_DRAWS(1);
}

virtual void
update(float delta);

{
if (!m_bStartingPositionInitialized)
{
return;
}

delta *= m_fFadeDelta;

unsigned int newIdx, newIdx2, i, i2;
unsigned int mov = 0;

// Update current points
for(i = 0; i<m_uNuPoints; i++)
{
m_pPointState[i]-=delta;

if(m_pPointState[i] <= 0)
mov++;
else
{
newIdx = i-mov;

if(mov>0)
{
// Move data
m_pPointState[newIdx] = m_pPointState[i];

// Move point
m_pPointVertexes[newIdx] = m_pPointVertexes[i];

// Move vertices
i2 = i*2;
newIdx2 = newIdx*2;
m_pVertices[newIdx2] = m_pVertices[i2];
m_pVertices[newIdx2+1] = m_pVertices[i2+1];

// Move color
i2 *= 4;
newIdx2 *= 4;
m_pColorPointer[newIdx2+0] = m_pColorPointer[i2+0];
m_pColorPointer[newIdx2+1] = m_pColorPointer[i2+1];
m_pColorPointer[newIdx2+2] = m_pColorPointer[i2+2];
m_pColorPointer[newIdx2+4] = m_pColorPointer[i2+4];
m_pColorPointer[newIdx2+5] = m_pColorPointer[i2+5];
m_pColorPointer[newIdx2+6] = m_pColorPointer[i2+6];
}else
newIdx2 = newIdx*8;

const GLubyte op = (GLubyte)(m_pPointState[newIdx] * 255.0f);
m_pColorPointer[newIdx2+3] = op;
m_pColorPointer[newIdx2+7] = op;
}
}
m_uNuPoints-=mov;

// Append new point
bool appendNewPoint = true;
if(m_uNuPoints >= m_uMaxPoints)
{
appendNewPoint = false;
}

else if(m_uNuPoints>0)
{
bool a1 = ccpDistanceSQ(m_pPointVertexes[m_uNuPoints-1], m_tPositionR) < m_fMinSeg;
bool a2 = (m_uNuPoints == 1) ? false : (ccpDistanceSQ(m_pPointVertexes[m_uNuPoints-2], m_tPositionR) < (m_fMinSeg * 2.0f));
if(a1 || a2)
{
appendNewPoint = false;
}
}

if(appendNewPoint)
{
m_pPointVertexes[m_uNuPoints] = m_tPositionR;
m_pPointState[m_uNuPoints] = 1.0f;

// Color assignment
const unsigned int offset = m_uNuPoints*8;
*((ccColor3B*)(m_pColorPointer + offset)) = _displayedColor;
*((ccColor3B*)(m_pColorPointer + offset+4)) = _displayedColor;

// Opacity
m_pColorPointer[offset+3] = 255;
m_pColorPointer[offset+7] = 255;

// Generate polygon
if(m_uNuPoints > 0 && m_bFastMode )
{
if(m_uNuPoints > 1)
{
ccVertexLineToPolygon(m_pPointVertexes, m_fStroke, m_pVertices, m_uNuPoints, 1);
}
else
{
ccVertexLineToPolygon(m_pPointVertexes, m_fStroke, m_pVertices, 0, 2);
}
}

m_uNuPoints ++;
}

if( ! m_bFastMode )
{
ccVertexLineToPolygon(m_pPointVertexes, m_fStroke, m_pVertices, 0, m_uNuPoints);
}

// Updated Tex Coords only if they are different than previous step
if( m_uNuPoints && m_uPreviousNuPoints != m_uNuPoints ) {
float texDelta = 1.0f / m_uNuPoints;
for( i=0; i < m_uNuPoints; i++ ) {
m_pTexCoords[i*2] = tex2(0, texDelta*i);
m_pTexCoords[i*2+1] = tex2(1, texDelta*i);
}

m_uPreviousNuPoints = m_uNuPoints;
}
}

/* Implement interfaces */
virtual CCTexture2D*
getTexture(void);
virtual void
setTexture(CCTexture2D *texture); //set get 纹理
virtual void
setBlendFunc(ccBlendFunc blendFunc);
virtual ccBlendFunc
getBlendFunc(void); //set get BlendFunc
virtual GLubyte
getOpacity(void);
virtual void
setOpacity(GLubyte opacity); //set get Opacity

virtual void
setOpacityModifyRGB(bool bValue);
virtual bool
isOpacityModifyRGB(void);

/** When fast mode is enabled, new points are added faster but with lower precision(精密度) */
//快速模式开启时 新的点被更快的添加 但精密度降低
inline bool
isFastMode() { return m_bFastMode; }
inline void
setFastMode(bool bFastMode) { m_bFastMode = bFastMode; }

//起点是否初始化

inline bool
isStartingPositionInitialized() { return m_bStartingPositionInitialized; }
inline void
setStartingPositionInitialized(bool bStartingPositionInitialized)
{
m_bStartingPositionInitialized = bStartingPositionInitialized;
}
protected:
bool
m_bFastMode;
bool
m_bStartingPositionInitialized;
private:
/** texture used for the motion streak */
CCTexture2D* m_pTexture;
ccBlendFunc m_tBlendFunc; //ALPHA混合方案
CCPoint m_tPositionR; //当前拖尾起点位置

float m_fStroke; //拖尾线条的宽度,越大当前越粗
float m_fFadeDelta; //每秒条带渐隐的alpha值减少量
float m_fMinSeg; //拖尾中用于划分条带的顶点的最小距离。

unsigned int m_uMaxPoints; //顶点最大数量
unsigned int m_uNuPoints; //当前的顶点数量
unsigned int m_uPreviousNuPoints; //上次的顶点数量

/** Pointers */
CCPoint* m_pPointVertexes; //顶点位置数组
float* m_pPointState; //顶点的状态值数组,这个状态值取值为0~1.0间,代表了消隐程度,其实就是alpha值。

// OPENGL所用的顶点各类数据绘冲
ccVertex2F* m_pVertices; //位置
GLubyte* m_pColorPointer; //颜色
ccTex2F* m_pTexCoords; //纹理UV
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐