本文主要是介绍CCMotionStreak(ccnode子类 可实现拖尾效果 需要设置--- 消隐动画时长,拖尾条带相邻顶点间的最小距离,拖尾条带的宽度,顶点颜色,纹理),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
例子:
以下示例出自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
};
这篇关于CCMotionStreak(ccnode子类 可实现拖尾效果 需要设置--- 消隐动画时长,拖尾条带相邻顶点间的最小距离,拖尾条带的宽度,顶点颜色,纹理)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!