1.背景
想要在Jump项目中实现武器运动的拖影效果(如D3中的风剑,War3 Dota中剑圣A杖),查了查Cocos2dx的资料,发现cocosdx已经准备好了一个CCMotionStreak来帮助我们实现这个效果。在将这个效果实际的添加入项目时遇到了一些问题,做个总结。
2.CCMotionStreak效果类的解析
抽象的来看CCMotionStreak, 它的重要组成部分如下:
1.一个抽象渲染信息队列, 由三个具体的队列组成:
a.ccVertex2F* m_pVertices; //an array which holds the Vertics position data
b.GLubyte* m_pColorPointer; //an array holds color data which can be used for the blend func(PROBABLY!)
c.ccTex2F* m_pTexCoords; //an array holds the Texture coords data.
2. 三个重要方法:
a. void MyCCMotionStreak::setPosition(const CCPoint& position)
b.void MyCCMotionStreak::update(float delta)
c.void MyCCMotionStreak::draw()
CCMotionStreak的过程:
1.初始化完毕
2.通过在某一处调用 MyCCMotionStreak::setPosition传入给 MyCCMotionStreak一个坐标point1.
3.在update方法中有如下过程:
a.分析此时的顶点队列,将过时的信息从渲染队列中删除。
b.根据从step2中得到的point1, 生成新的渲染信息,将这些信息加入到渲染信息队列之中。
4.draw方法绘制:
我们的渲染信息队列中保存了三个重要的信息:
a. 顶点坐标信息
b. 贴图坐标信息
c. 颜色混合信息
有个这三个信息,就可以使用Opengl提供的方法将拖影绘制出来
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);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)m_uNuPoints*2); //draw those information as a trangle strip.
当然在draw方法里还有blendfunc的设制,在这里不在贴代码了。
以上!我们所设定的运动拖影就可以在窗口中绘制出来 。
3. CCMotionStreak的疑问。
1.在一个CCMotionStreak初始化完毕之后, 我们必须将其加入到某一个父结点之中, 并调用setPosition更新坐标信息, 传入的坐标信息也必须是相对这个父结点的node space coords!
如果我们是想要在屏幕中添加一个鼠标运动轨迹, 我们的代码逻辑是:在屏幕layer中添加一个CCMotionStreak,这个streak的运动坐标由onTouchedMoved来更新。
这样的逻辑在这个情形下还比较的合理。
但是如果是这个情形:我们想要给屏幕中的主角的武器上添加一个运动轨迹。 我们的代码逻辑此时还是:在屏幕layer中添加一个CCMotionStreak,这个streak的运动坐标由武器的位置来更新。
这时,这段更新位置的代码写在哪里合适(layer的update方法之中?), 由谁来负责更新?
还放在Layer之中吗? 这样我们就给这个layer注入的新的代码, 倘若我想要添加十个CCMotionStreak效果, 我就要在layer之中添加十段新的代码, 这样不好。
其时最好的代码逻辑应该就是:我们为主角的武器上添加一个效果。
这个添加效果的过程在代码上不应该与除武器其他的代码产生关联,更不应该向layer中注入新的代码。
等着接着写。