cocos2dx的骨骼动画代码编辑器Cocos ->支持-> CocoStudio文件夹,赢得通过过滤、文件结构如下。(在Mac的领导下,没有一点的一坨。)


电枢(目录):

动画(目录):动画控制。
CCProcessBase(文档):
processbase(类):对cctween和armatureanimation基类。
cctween(文档):
吐温(class):控制Flash中的图层动画。
ccarmatureanimation(文档):
armatureanimation(类):有一个以上的吐温整个动画控制。
数据(目录):XML或JSON转换成数据结构直接用于C++。
CCDatas(文档):
基础数据(类):对bonedata和framedata基类,包括有关的尺寸和位置的颜色信息。
显示数据(类):对spritedisplaydata,armaturedisplaydata基类,并particledisplaydata。
spritedisplaydata(类):骨骼中显示数据。
armaturedisplaydata(类):
particledisplaydata(类):
薄讷大塔(类):一个单一的骨骼数据,并在Flash一层骨架。
armaturedata(类):骨骼数据,整个骨的结构数据。
framedata(类):关键帧数据。
movementbonedata(类):关键帧骨骼数据。
行为特征(类):一个完整的动画数据。
animationdata(类):群体动画数据,包括多个行为特征。
contourdata(类):
texturedata(类):显示图像数据。
工具(目录):
ccarmaturedatamanager(文档):
数据(类):
armaturedatamanager(类):管理armaturedata,animationdata,和texturedata。
CCArmatureDefine(文档):
CCDataReaderHelper(文档):
_asyncstruct(类):
_DataInfo (class):
DataReaderHelper(级):这是解析XML或JSON类。
CCSpriteFrameCacheHelper(文档):
SpriteFrameCacheHelper(类):
CCTransformHelp(文档):
transformhelp(类):矩阵运算。
CCUtilMath(文档):
ccarmature(文档):
电枢(类):与armatureanimation和armaturedata整个骨骼动画控制。
CCBone(文档):
骨骼(类):骨骼控制类
显示(目录):显示图片管理。
CCBatchNode(文档):
BatchNode(类):
CCDecorativeDisplay(文档):
DecorativeDisplay(类):
CCDisplayFactory(文档):
displayfactory(类):
ccdisplaymanager(文档):
displaymanager(类):
CCSkin(文档):
皮肤(类):
物理(目录):物理引擎相关,不分析。
ColliderFilter(文档):
ColliderFilter(类):
ColliderBody(类):
ColliderDetecotor(类)


数据相关源代码

从底层到高层的一类分析

让我们看看与数据相关的UML。总的来说,armaturedatamanager依靠datareaderhelper解析XML文件从出口闪进xxdata是直接使用的程序,xxdata对应的XML节点,如framedata对应的节点()。


基础数据

数据:它是用来表示位置,旋转的骨架或框架颜色和变焦。


数据的。

类数据:公共cocosd::裁判
{
公共:
/ /计算两个数据之间的值(以从)和设置为自
虚减(数据*,数据*,BOOL限制);
公共:
xml位置,x,y
x;
浮Y;
z在xml中
Int zOrder;
XML / KX,肯塔基旋转。
Float skewX;
浮skewy;
xml缩放
浮scaleX;
浮称;

浮tweenrotate;
更改颜色属性
布尔isusecolorinfo;
a,r,g,b;
};


作为framedata和bonedata基地,提供骨骼的状态信息。从下面,我们可以看到,bonedata对应于在> XML的B节点和framedata对应的XML节点,都bonedata和framedata。

一个属性,这些属性以代表。

bonedata

bonedata对应于XML节点B的>


bonedata:公共数据类
{
公共:
无效adddisplaydata(显示数据*显示数据);
* getdisplaydata(int index)显示数据;
公共:
STD::字符串名称!
std::string parentname骨母的名字; / /!
保存、显示、数据信息 / /骨!
Cocosd::矢量displaydatalist;
仿射转换,程序似乎没有使用这个属性。
Cocosd::点bonedatatransform;
};


有displaydatalist在bonedata,这是用来把皮肤上的骨(显示数据)。显示数据对应的结在XML节点。在bonedata有多种皮肤,和许多功能如皮肤更换是必要的。

framedata

framedata对应的XML节点,这是在Flash的关键帧信息。


framedata:公共数据类
{
公共:
国际frameid;
在这个框架中的长度
国际时间;
我不知道他应该做什么。
布尔istween;
显示图形的xml中的DI
国际displayindex;
};


显示数据

显示数据是spritedisplaydata,armaturedisplaydata,和particledisplaydata母,这是用来表示显示节点信息。

armaturedata

armaturedata是这个骨架的所有骨骼的相应节点,这可以看作是骨骼动画的骨架。


armaturedata类:公共cocosd::裁判
{
公共:
添加骨骼信息
无效addbonedata(bonedata * bonedata);
bonedata * getbonedata(const std::string bonename);
公共:
字符串名;
更多骨骼信息
Cocosd::地图bonedatadic;
浮dataversion;
};


animationdata

animationdata对应有多个行为特征节点,和行为特征(下)对应于XML的乐章,这是在Flash帧标签。


animationdata类:公共cocosd::裁判
{
公共:
无效addmovement(行为特征* movdata);
行为特征* getmovement(const std::string movementname);
ssize_t getmovementcount();
公共:
以名称
字符串名;
所有动画帧标签
Cocosd::地图movementdatadic;
所有动画帧标签名称
std::vector movementnames;
};


行为特征

行为特征对应的XML >所有骨架movementbonedata(B在MOV)。


类的行为特征:公共cocosd::裁判
{
公共:
无效addmovementbonedata(movementbonedata * movbonedata);
movementbonedata * getmovementbonedata(const std::string bonename);
公共:
字符串名;
xml中的DR
国际时间;
这是怎么回事
浮秤;
以xml
Int durationTo;
drtw / / XML
Int durationTween;
xml中的LP
布尔环;
获取/框架信息骨骼
Cocosd::地图movbonedatadic;
};



movementbonedata

movementbonedata对应于B中的XML,与framelist它,即关键帧信息。


movementbonedata类:公共cocosd::裁判
{
无效addframedata(framedata * framedata);
framedata * getframedata(int index);
公共:
xml中的dl
浮动延迟;
xml中的SC
浮秤;
这 / /和行为特征在时间不是吗
浮动时间;
字符串名;
关键帧信息
Cocosd::矢量framelist;
};


小总结

各节点之间的对应关系的XML和xxdata如下表,并对XML的每个字段的含义可以参考在上一篇文章


看看动画相关的代码


armaturedatamanager

armaturedatamanager使用datareaderhelper解析armaruredatas,animationdatas和_texturedatas。

armaturedatamanager是一个简单的例子,用动画来获取数据在armaturedatamanager生成动画。


armaturedatamanager类:公共cocosd::裁判
{
公共:
单个案例
静态armaturedatamanager * getInstance();
静态destroyinstance();
公共:
无效addarmaturedata(const std::string ID,armaturedata * armaturedata,const std::string configfilepath =));
armaturedata * getarmaturedata(const std::string ID);
无效removearmaturedata(const std::string ID);
无效addanimationdata(const std::string ID,animationdata * animationdata,const std::string configfilepath =));
animationdata * getanimationdata(const std::string ID);
无效removeanimationdata(const std::string ID);
无效addtexturedata(const std::string ID,texturedata * texturedata,const std::string configfilepath =));
texturedata * gettexturedata(const std::string ID);
无效removetexturedata(const std::string ID);
Void addArmatureFileInfo (const std:: string configFilePath);
const cocosd::地图getarmaturedatas()const;
const cocosd::地图getanimationdatas()const;
const cocosd::地图gettexturedatas()const;
受保护的:
无效addrelativedata(const std::string configfilepath);
数据* getrelativedata(const std::string configfilepath);
私人:
Cocosd::地图_armaruredatas;
Cocosd::地图_animationdatas;
Cocosd::地图_texturedatas;
std::unordered_map _relativedatas;
};



主要是armaruredatas,animationdatas,_texturedatas三地图,然后这些三地图制作的当执行


armaturedatamanager::getInstance()-> addarmaturefileinfo(dran。XML);




之后,三个地图的变化所产生的addarmaturefileinfo代码如下。


无效armaturedatamanager::addarmaturefileinfo(const std::string configfilepath)
{
addrelativedata(configfilepath);
_autoloadspritefile =真;
DataReaderHelper::getInstance()-> adddatafromfile(configfilepath);
}


也被称为datareaderhelper::getInstance()-> adddatafromfile(),它是已知的,datareaderhelper真的已经完成了数据分析。

在datareaderhelper班,有一堆decodexxx()(如decodearmature,decodebone)解析的xml.look节点下

adddatafromfile这个代码:


无效datareaderhelper::adddatafromfile(const std::string文件路径)
{
省略一些代码

datainfo datainfo;
datainfo.filename = filepathstr;
datainfo.asyncstruct = nullptr;
datainfo.basefilepath = basefilepath;
如果为
{
DataReaderHelper::adddatafromcache(contentstr,datainfo);
}
else if(str = =。JSON| | STR = 。exportjson )
{
DataReaderHelper::adddatafromjsoncache(contentstr,datainfo);
}
如果(isbinaryfilesrc)
{
DataReaderHelper:: addDataFromBinaryCache (contentStr.c_str (), dataInfo);
}

cc_safe_delete_array(pbytes);
}


对应不同的文件(XML,JSON,二进制)解析,XML作为adddatafromcache


无效datareaderhelper::adddatafromcache(const std::string pfilecontent,datainfo * datainfo)
{



有三decodearmature,分别decodeanimation,decodetexture,armaturedata,animationdata,texturedata的armaturedatamanager形成后:(-> addarmaturedata):getInstance,addanimationdata,addtexturedata,图中对应的armaturedatamanager。在decodexxx,各种decodexx来生成相应的xxxdata。

电枢

加载XML数据之后,调用


电枢=电枢::创造(画);
电枢-> getanimation()->玩(走);
电枢-> getanimation()-> setspeedscale();
电枢-> setPosition(visiblerect::中心(),x,visiblerect::中心()。Y *。F);
电枢-> setScale(F);
addChild(电枢);


它显示了动画,那么这是怎么做的呢

代码的电枢部分如下:armatureanimation控制XML的MOV的节点,和吐温在骨,对应于B(movementbonedata)XML。


类:公共cocosd电枢::节点、公共cocosd::BlendProtocol {
受保护的:
/ /显示动画armaturedata
armaturedata * _armaturedata;
batchnode * _batchnode;
* _parentbone骨;
浮_version;
可变的布尔_armaturetransformdirty;
所有的/骨
Cocosd::::矢量地图_bonedic;cocosd _topbonelist;

Cocosd::blendfunc _blendfunc;
Cocosd::VEC _offsetpoint;
Cocosd::VEC _realanchorpointinpoints;
动画控制器
armatureanimation * _animation;
};





部分的代码如下,tweendata是目前骨的状态,每一帧都更新这个值,并使用tweendata确定worldinfo肌肤显示信息。吐温是骨整个动画过程。


类骨:公共cocosd::节点{
受保护的:
bonedata * _bonedata;

弱引用到/电枢!
* _armature电枢;

弱引用!孩子电枢
* _childarmature电枢;

displaymanager * _displaymanager;

*
*当电枢播放动画,如果没有一个movementbonedata的
*设置ignoremovementbonedata为真,那么这骨也会显示。
* /
布尔_ignoremovementbonedata;

Cocosd::blendfunc _blendfunc;
布尔_blenddirty;

吐温* _tween; / /计算中的影响!

用于制作吐温效果!在每一帧
framedata * _tweendata;

骨* _parentbone弱引用; / /母!
布尔_bonetransformdirty;不脏 / /是否变换!

自我转换,使用这个/!改变显示器的状态
Cocosd::垫_worldtransform;

_worldinfo数据*;

母骨/髓母细胞!
* _armatureparentbone骨;

};



吐温

这是一个骨骼动画的过程中,看到movementbonedata below.tweendata是参考tweendata骨,这tweendata值在每一帧的计算。


类吐温:公共processbase {
受保护的:
弱引用!目前movementbonedata。数据在数据池中。
movementbonedata * _movementbonedata;

framedata * _tweendata计算中间帧; / /!数据,弱引用!骨的tweendata
framedata * _from; / /帧数据,用于!计算之间的值
framedata * _to; / /帧数据,用于!计算之间的值

差异管理/总
framedata * _between; / /帧间数据,用于!目前framedata(m_pnode)值的计算

骨* _bone弱引用; / /骨!

tweentype _frametweeneasing;其中吐温效应电流 / /确定!框架的使用

国际_betweenduration;关键帧将持续 / /电流!_betweenduration帧

多少钱/总运行框架关
国际_totalduration;

国际_fromindex / ;在当前帧的索引/!framelist的movementbonedata,它不同于m_iframeindex
国际_toindex / ;在下一帧的索引/!framelist的movementbonedata,它不同于m_iframeindex

armatureanimation * _animation;

布尔_passlastframe;当前帧索引 / /如果!超过最后一帧的索引
};



armatureanimation

控制动画,剧中看到_tweenlist,所有骨骼动画。


armatureanimation类:公共processbase {
受保护的:
animationdata保存所有movementdatas这 / /!动画的应用。
animationdata * _animationdata;

行为特征* _movementdata;保存所有movementframedatas这 / /行为特征!动画的应用。

电枢* _armature;电枢 / /一个弱引用!

std::string _movementid; / /电流运动的名字!

国际_toindex的帧索引; / /!行为特征-> m_pmovframedataarr,它不同于m_iframeindex。

cocos2d::矢量_tweenlist;
}


如何更新每一帧的骨骼

通过addChild(电枢),onenter在armaure(节点将在舞台上,调用addChild等),onenter调scheduleupdate,调整scheduleupdatewithpriority调整_scheduler -> scheduleupdate.in这样,电枢的更新是每帧调用。


空电枢::更新(浮点dt)
{
_animation ->更新(DT);
(const为自体骨:_topbonelist){
骨骼更新(DT);
}
_armaturetransformdirty = false;
}



动画-更新(DT)也被调用,而遍历被称为骨骼>更新(DT);动画>更新(DT)如下所示:


无效armatureanimation::更新(浮DT)
{
processbase::更新(DT);

对于(const汽车吐温:_tweenlist)
{
吐温更新(dt);
}
一堆代码/省略号
}



吐温->更新(DT)被调用;每次更新会给updatehandler(更新在更新在ProcessBase称为updatehandler)


无效:updatehandler之间:()
{
一堆代码/省略号
如果(_looptype > animation_to_loop_back)
{
%=updateframedata(百分比);
}

如果(_frametweeneasing!=::::::cocosd tweenfunc tween_easing_max)
{
TweenNodeTo(百分比);
}
}



TweenNodeTo称tweennodeto,那里的tweendata实际上是骨tweendata。按百分比变化量_tweendata。


framedata *吐温::tweennodeto(浮动率,framedata *节点)
{
节点=结= = nullptr _tweendata:节点;

如果(!_from -> istween)
{
% =;
}

节点-> x = _from -> x + % * _between -> X;
节点-> Y = _from -> Y + % * _between -> Y;
节点-> scaleX = _from -> scaleX + % * _between -> scaleX;
节点->称= _from ->称以上* _between ->称;
节点-> skewx = _from -> skewx + % * _between -> skewx;
节点-> skewy = _from -> skewy + % * _between -> skewy;

_bone -> settransformdirty(真的);

如果(节点_between -> isusecolorinfo)
{
tweencolorto(%,节点);
}

返回节点;
}



在一个大圆圈,在骨tweendata在每帧更新,和骨更新终于看了,并在tweendata计算的基础是worldinfo和worldtransform。此外,updatedisplay更新皮肤的信息,staticcast(显示)-> updatearmaturetransform(),然后变换= transformconcat(_bone -> getnodetoarmaturetransform())。


空骨::更新(浮三角洲)
{
如果(_parentbone)
_bonetransformdirty = _bonetransformdirty(_parentbone -> istransformdirty)| |;

如果(_armatureparentbone!_bonetransformdirty)
{
_bonetransformdirty = _armatureparentbone -> istransformdirty();
}

如果(_bonetransformdirty)
{
如果(_dataversion = version_combined)
{
transformhelp::nodeconcat(* _tweendata,* _bonedata);
- = _tweendata -> scaleX;
- = _tweendata ->称;
}

_worldinfo ->复制(_tweendata);

_worldinfo -> x = _tweendata -> x + x _position;
_worldinfo -> Y = _tweendata -> Y + _position。Y;
_worldinfo -> scaleX = _tweendata -> scaleX * _scalex;
_worldinfo ->称为_tweendata ->称* _scaley;
_worldinfo -> skewx = _tweendata -> skewx + _skewx + _rotationz_x;
_worldinfo -> skewy = _tweendata -> skewy + _skewy - _rotationz_y;

如果(_parentbone)
{
applyparenttransform(_parentbone);
}
其他的
{
如果(_armatureparentbone)
{
applyparenttransform(_armatureparentbone);
}
}

transformhelp::nodetomatrix(* _worldinfo,_worldtransform);

如果(_armatureparentbone)
{
_worldtransform = transformconcat(_worldtransform,_armature -> getnodetoparenttransform());
}
}

displayfactory::(这updatedisplay,三角洲,_bonetransformdirty | |(_armature -> getarmaturetransformdirty));

(const对象:对汽车_children){
骨* childbone = static_cast(obj);
childbone ->更新(三角洲);
}

_bonetransformdirty = false;



如何显示(画)出的图片(皮肤)

电枢诗节点,在添加父节点后,调用它的绘制函数,遍历绘制的骨骼显示元素。


无效:电枢:画(cocosd:*:渲染器渲染,const垫变换,uint_t标志)
{
如果(_parentbone = = = = _batchnode nullptr nullptr)
{
( / / cc_node_draw_setup);
}


为(自动对象:_children)
{
如果(骨头骨= dynamic_cast(对象))
{
节点节点=骨-> getdisplayrendernode();

如果(nullptr =节点)
继续;

开关(骨-> getdisplayrendernodetype())
{
Case CS_DISPLAY_SPRITE:
{
皮肤皮肤= static_cast(节点);
皮肤-> updatetransform();

blendfunc功能=骨-> getblendfunc();

如果(func.src!= _blendfunc.src | | func.dst!= _blendfunc DST)。
{
皮肤-> setblendfunc(骨-> getblendfunc());
}
其他的
{
皮肤-> setblendfunc(_blendfunc);
}
皮肤->绘制(渲染器,变换,标志);
}
打破;
案例cs_display_armature:
{
节点->绘制(渲染器,变换,标志);
}
打破;
违约:
{
节点->访问(渲染器,变换,标志);
( / / cc_node_draw_setup);
}
打破;
}
}
如果(节点节点= dynamic_cast(对象))
{
节点->访问(渲染器,变换,标志);
( / / cc_node_draw_setup);
}
}
}




然后皮肤->绘制(渲染、变换、旗);新更新的_quad将用来显示最新的图片信息。


{
Mat MV =导演::getInstance()-> getmatrix(matrix_stack_type::matrix_stack_modelview);

执行z顺序
_quadcommand.init(_globalzorder,_texture -> getName(),(),getglprogramstate _blendfunc,_quad,MV);
渲染-> addCommand(_quadcommand);
}



在这一点上,你应该在骨骼动画cocos2dx全面了解,三篇文章在粗糙的,但有些细节我不了解,但不要在意这些细节,没有现实需求的变化,了解80%就可以了,要仔细了解所需要的细节。