cocos2dx的MotionStreak.cpp解析(-)

  本来是因为工作项目的原因,需要做一个类似“刀光剑影”的特效,类似蓝杖剑圣的效果,因为是动态的,美术出图不太能实现这种效果,所以就想着用opengl的方式实现。

  虽然读了不少opengl的书,英文中文的都有,基本每次读都有收获。网上也有不少的opengl教程,读的时候感觉都能理解,但是当自己下手写的时候,有种无从下手的感觉,就在群里问了下思路,大神们回答很简单,就是一个三角形带直接搞定。后来发现cocos2dx已经有一个现成的特效了,就是motionstreak,欣喜之余看了下源码,把自己的想法记录下来与大家共享,水平有限,错误之处请指正,共同进步。

  opengles中有三种基本的图元,点线和三角形,点主要用在粒子系统,最常用的就是三角形,我们看到的做工精美的3D模型就是很多三角形组成的,三角形的数量也就决定了模型的精细程度,因为在我们的需求里用三角形就措措有余了,何况还是2d的特效

  思路大体如下:我们的这个特效是个三角形带,这个特效不管是跟着刀刃走还是跟着人走(下文我们就把特效跟随的目标,就是这里的人或着刀刃,叫做特效的载体),其实都是动态变化的,也就要求我们动态更新这个三角形带,不断向三角行带中加入定点和移除定点。顶点什么时候移除有两种方式,一种是每个顶点都有个生存周期,过了生命周期的时间就会被移除。第二种是规定一个顶点个数的上限,超过顶点个数就会被移除。cocos2dx里面是通过给每个顶点设置一个生存时间来控制顶点移除的,带回代码里面会讲到。那么如何向三角形带中添加顶点呢,因为这个特效总是跟着载体走,因此我们首先想到应该用载体的位置来生成三角形的顶点加入到三角形带中,cocos2dx里面是把载体的位置放在了 Point* _pointVertexes 里面,而把生成的三角形带中的点放到了 Vertex2F* _vertices 里面。

  这里需要注意一下的是,我们不能直接把载体的位置直接加载三角形带中,而是根据这个位置生成两个顶点,这个就是这个动态特效的关键。

  那么如何根据一个载体的位置的点生成三角形带中的两个顶点呢?一般是取上一个载体的位置,跟当前载体的位置形成一个向量v1,再计算这个向量的垂直向量v2,因为我们这个特效是有宽度的,创建这个特效的时候会在参数里传入,根据我们传入的宽度stroke,得到v2向量上的两个点,放入到三角形带当中(可以把这两个顶点看做是一个小组,方便我们理解,并且在设置纹理坐标的时候,这两个顶点的v分量是相同的,u分量一个是0,一个是1,大家可以想像一下)。下面的代码中会有注释。依此类推,这样就产生了这个动态变化的三角形带。

  这个特效是可以自定义纹理的,因此也就需要设置纹理坐标,上面稍微提到了一下。总的思路就是每次更新完三角形带,根据三角形带中顶点的个数重新设置下v分量。u分量比较简单,非1即0。(这个的u相当于x,v相当于y,并且范围从0到1)

  通过OpenGL赋予纹理坐标和纹理贴图就可以画出来了。

  啰嗦了这么多,下面是具体的代码。

  最重要的两个函数是:

    void MotionStreak::update(float delta)

    void MotionStreak::onDraw(const kmMat4 &transform, bool transformUpdated)

  我们应该从这两个方法入手,显然 update方法是动态更新三角形带的,而onDraw方法则是把当前的三角形带绘制出来。

  下一篇主要讲代码。

  

  

  

时间: 2024-08-01 21:45:29

cocos2dx的MotionStreak.cpp解析(-)的相关文章

cocos2dx 读取json及解析

ball.json 数据例如以下: { "entities": [ { "entity": { "TapOpposite": 0, "Interval": 0.95, "BallNum": 1 } }, { "entity": { "TapOpposite": 0, "Interval": 0.91, "BallNum": 2

cocos2dx 自动添加cpp文件到android.mk

将 LOCAL_SRC_FILES := hellocpp/main.cpp ../../Classes/AppDelegate.cpp ../../Classes/HelloWorldScene.cpp 修改成 FILE_LIST := hellocpp/main.cpp FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/*.cpp) LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%) coc

cocos2dx android平台事件系统解析

对于cocos2dx在android平台事件的响应过程很模糊,于是分析了下源码,cocos2dx 版本3.4,先导入一个android工程,然后看下AndroidManifest.xml <application android:label="@string/app_name" android:icon="@drawable/icon"> <!-- Tell Cocos2dxActivity the name of our .so --> &

`cocos2dx 非完整` UI解析模块

昨天在cocos2dx的一个群里,遇到一位匿名为x的朋友询问的问题,是关于ui的.他使用c++写了不少的ui封装节点,用来实现游戏中的各种不同效果.然后现在想改用lua,于是尝试使用最小代价去复用自己的代码.当然这个是可以做到的,相信很多人都是知道方法的.今天的这篇文章就来谈谈ui部分的处理以及个人的见解. 我们都知道,cocos2dx引擎提供了ui工具cocostudio.后来改名为cocos engine.这些就不赘述了,很多人都会使用这款工具.新版本的工具我没有使用过,不过我承认是方便了很

cocos2d-x使用tinyxml2存储解析xml

我用的是2.1.4的cocos2d-x,里面自带有tinyxml2库. 导入头文件:#include "support/tinyxml2/tinyxml2.h" using namespace tinyxml2; 一:创建xml并保存 void TinyXmlDemo::createTinyXMLFile() { //储存XML文件的路径 std::string filePath = CCFileUtils::sharedFileUtils()->getWritablePath(

(16)Cocos2d-x 多分辨率适配完全解析

Overview 从Cocos2d-x 2.0.4开始,Cocos2d-x提出了自己的多分辨率支持方案,废弃了之前的retina相关设置接口,提出了design resolution概念. 3.0中有以下相关接口: Director::getInstance()->getOpenGLView()->setDesignResolutionSize() //设计分辨率大小及模式 Director::getInstance()->setContentScaleFactor() //内容缩放因子

cocos2d-x内存管理机制解析(转载)

最近在看内存管理的源码,发现这篇文章讲的不错,思路很清晰,故转载收藏. 原地址:http://blog.csdn.net/a7833756/article/details/7628328 1.cocos2d-x 内存管理的方式,cocos2d-x采用引用计数的方式进行内存管理,当一个对象的引用计数为0的时候,就会被引擎自动delete掉. 所有cocos2d-x里面的类都继承ccobject类(应该是吧.),下面看ccobject类源码: 这里 m_uReference 就是引用计数,在对象构造

cocos2D-x 3.5 引擎解析之--引用计数(Ref),自己主动释放池(PoolManager),自己主动释放池管理器( AutoreleasePool)

#include <CCRef.h> Ref is used for reference count manangement. If a classinherits from Ref. Class Ref 为引用计数类,用来管理对象的引用计数. 这样就不会出现还有指针保持指向该对象,当使用该指针操作时,假设指向的对象被销毁就会出现程序异常. class CC_DLL Ref { public: void retain();//添加引用计数一次 void release();//降低引用计数一次

cocos2D-x 3.5 引擎解析之--节点(Node)

#ifndef __CCNODE_H__ #define __CCNODE_H__ #include "base/ccMacros.h" #include "base/CCVector.h" #include "base/CCProtocols.h" #include "base/CCScriptSupport.h" #include "math/CCAffineTransform.h" #include