求助,spine中用spine 骨骼动画 素材控制mesh的变形

骨骼动画 Spine的使用(With Cocos2d-x)
Spine的使用(With Cocos2d-x)
Spine是一个2D的骨骼动画编辑器, 因为其良好的UI设计及完整的功能, 在kickstarter上发布以后立即收到追捧, 作为一个几乎只有游戏开发者才会使用的小众工具, 募集了远超目标5倍的资金, 共计6.7W多美元. 我在其项目发布后, 成为了Spine在kickstarter的早一批backer, 这是我在kickstarter上第一个, 也是目前唯一一个支持的项目. 随后, 通过不断收到的邮件见证了Spine逐步完善的过程, 直到其发出target完成的邮件. 又过了这么长时间了, 因为手头的项目一直不需要太复杂的2D骨骼动画,
拖着没有研究, 现在也是时候看看Spine了, 可惜的是, Spine的使用还有一系列的可以参考, 而Spine的Runtime使用完全没有文档,
只有一两个简单的例子. Spine团队的主要精力目前还是放在一些新功能的开发和Runtime的继续支持上, 写文档还排在上.
简单的循环动画
编辑上看视频教程吧, 只是打包文件需要使用的libgdx的Data Format来导出, 后缀改为atlas.
然后, 从例子中能学到的东西:
比如在一个node中, 按如下代码可以创建一个spineboy行走的动画, 并且循环播放.
skeletonNode = new CCSkeletonAnimation(&spineboy.json&, &spineboy.atlas&);
skeletonNode-&setAnimation(&walk&, true);
CCSize windowSize = CCDirector::sharedDirector()-&getWinSize();
skeletonNode-&setPosition(ccp(windowSize.width / 2, 20));
addChild(skeletonNode);
skeletonNode-&release();
播放一次动画
简单的情况, 播放一次动画后就不管了, 那么直接使用CCSkeletonAnimation::setAnimation, 并且以false为第二个参数就好了.
更复杂的情况, 需要知道什么时候这个动画播放完了, 因为Spine的Runtime中没有动画结束的回调(这是另外一种良好的设计), 只能通过在update中判断. 更进一步的悲剧是, 在cocos2d-x的Runtime中中没有简单的判断方法, example中给了一个方法:
if (skeletonNode-&states[0]-&loop) {
if (skeletonNode-&states[0]-&time & 2) skeletonNode-&setAnimation(&jump&, false);
if (skeletonNode-&states[0]-&time & 1) skeletonNode-&setAnimation(&walk&, true);
这里使用的方法是判断播放时间, 我对此方法表示强烈的反感, 也绝对的建议大家不要使用, 因为你不仅需要预先知道每个动画播放的时长, 而且任何时候你改动了动画的播放时间, 这个代码都得回来改, 这样做根本就违反我们使用编辑器的初衷, 甚至我觉得在Runtime的example中给出这种代码是非常不负责任的行为. 这个方法只在一种情况下使用, 那就是你的确是想要在某个动画播放的确定时间干某个事情,
不过这种情况应该非常少见.
在的确需要知道播放完一次动画时, 我建议用以下方式来完成, 因为没有现成的C++接口, 这里借用了一个C代码中的函数来完成工作:
if(AnimationState_isComplete(skeletonNode-&states[0])) {
if ( 0 == strcmp(skeletonNode-&states[0]-&animation-&name, &walk&) ) {
skeletonNode-&setAnimation(&jump&, false);
skeletonNode-&setAnimation(&walk&, false);
连续播放动画
上面那个例子中的动画连续动画播放可以直接通过CCSkeletonAnimation::addAnimation接口来完成, 这样更加简单.
skeletonNode = new CCSkeletonAnimation(&spineboy.json&, &spineboy.atlas&);
skeletonNode-&addAnimation(&walk&, false);
skeletonNode-&addAnimation(&jump&, false);
skeletonNode-&addAnimation(&walk&, true);
但是失去了一些灵活性, 并且, Spine还不支持将多个动画接起来作为一个完整的动画使用, 这个挺弱的, 再加上Spine工具本身就没有连接多个动画的功能, 就更加弱了.
程序控制的骨骼动画
所谓程序控制的骨骼动画, 就是类似Spine宣传动画中那样, Globin的目光跟随着鼠标的移动. 这个功能的实现, 应该算是骨骼动画中最酷的一部分了. 传统的序列帧动画完全无法实现, 要实现的话还是得在序列帧外拆分肢体, 然后单独实现.
在骨骼动画中, 可以直接取到骨骼, 然后调整骨骼, 实现这样的效果, 要方便很多. 在Spine中取得骨骼的函数是CCSkeletonAnimation::findBone,
其他的就是设置rotation就行了.
void ExampleLayer::ccTouchesMoved(CCSet *touches, CCEvent *event) {
CCTouch* touch = (CCTouch*)touches-&anyObject();
CCPoint pos = touch-&getLocation();
Bone* head = skeletonNode-&findBone(&head&);
CC_ASSERT(head != nullptr);
float tanValue = (pos.y - head-&worldY) / (pos.x - head-&worldX);
float rotation = atan(tanValue) * 180 / 3.1415;
head-&rotation = rotation;
需要注意的是, 动画本身要是在播放的话, 不能动这个骨骼(被parent牵引是OK的), 不然的话会被动画本身强制改变, 看不到touch带来的效果.
慢动作和快动作
设置CCSkeletonAnimation的timeScale值.
对于一般情况下, 动画的切换要求两个动画完全能衔接上, 不然会出现跳跃感, 这个对于美术来说要求很高, 而Spine加了个动画混合的功能来解决这个问题. 使得不要求两个动画能完全的衔接上.
比如上面的walk和jump动画, 就是衔接不上的, 直接按上面的办法切换, 会出现跳跃, 但是加了混合后, 看起来就很自然了. 哪怕放慢10倍速度观察, 也完美无缺. 这个功能在序列帧动画时是无法实现的, 也是最体现Spine价值的一个功能. 代码如下:
skeletonNode-&setMix(&walk&, &jump&, 0.3f);
skeletonNode-&setMix(&jump&, &walk&, 0.3f);
Spine的出现, 对于2D骨骼动画编辑工具来说, 绝对是翻天覆地的变化, 划时代的. 这也再次说明了自己的问题, 因为和以前的同事说了很久了, 其实我们需要一个这样的编辑器, 但是自己却从来没有写过一个-_-! 当然, 我们当时讨论的是做一个开源的. 但是, Spine毕竟刚刚出现, 其实还是有不少的问题. 如下:
工具使用上
Spine的Runtime有些太马虎了, 问题相当多.
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?后使用快捷导航没有帐号?
只需一步,快速开始
&加载中...
查看: 16877|回复: 4
菜鸟也能学cocos2dx 3.0 骨骼动画spine
TA的其他好贴
马上注册,加入CGJOY,让你轻松玩转CGJOY。
才可以下载或查看,没有帐号?
首先我们来看到底什么是骨骼动画:在早期的机器上,渲染本身已经占用了很多CPU资源,因此,对于渲染,往往采取的是一种空间换时间的策略,以避免在模型的渲染中继续加重CPU的负担。
帧动画模型在这种条件下应运而生。比较著名的帧动画格式是Quake2所采用的MD2。
到今天为止,帧动画依然存在,只不过帧动画更多地是来描述小且动作相对少些的物体。
GPU出现后,CPU的问题早已不像以前那么突出,一些新的手段和技术也可以被应用进来了。
骨骼动画相对于帧动画而言,更加灵活多变,但同时,骨骼动画需要更多的计算量,因此骨骼动画往往应用在需要着重体现动作细节的模型中。
骨骼动画技术后于帧动画技术出现。
最开始,骨骼动画仅用于非实时渲染的建模领域,如3DMax这类建模软件之中,以方便美工的建模。
后来,CPU从渲染中解放后,骨骼动画才用于实时渲染的游戏中。
骨骼动画原理
骨骼动画的想法来源于人体骨骼。
例如说,人的上肢所有肌肉和皮肤都受上肢骨胳的影响,而人的踝关节则分别承受小腿骨胳和脚骨的影响。
根据这个我们可以将骨骼动画理解为两个概念: 骨骼:用以控制蒙皮的一种抽象的概念,如人体骨骼控制皮肤。 蒙皮:被骨骼控制、并显示在外的因素,如人体的皮肤被骨骼所影响。
骨骼动画原理:蒙皮(SKINMESH)
在最终的渲染结果中,蒙皮将完全显示出来,蒙皮实际上就是顶点、法线和纹理坐标等将被渲染的元素。
而其中,最关键的当然是顶点,顶点将直接被骨头牵扯运动,因而使得整个模型呈现骨骼所决定的样子。
骨骼动画原理:骨骼(SKELETON)
骨骼是一种抽象的概念,在最终的渲染结果中,它不可见。
类如人体骨骼、骨骼是若干骨头(Bone)成树状的集合体,而每块骨头又分别与若干数量的蒙皮顶点关联。
当骨头运动的时候,与之关联的所有蒙皮顶点也会受骨骼的影响而运动。
骨头与蒙皮顶点的关联需要考虑到每块骨头对蒙皮顶点的影响。 尽管大部分情况下,一个顶点将仅仅被一个骨头的影响,但是关节处的顶点往往被多根骨头影响,例如踝关节,可能会分别受小腿骨50%和脚骨50%的影响,这种影响叫作权重(Weight)。
在这种情况下,我们称踝关节的这些顶点,受小腿骨影响的权重是50%,受脚骨影响的权重也是50%。而在cocos2dx中常用的骨骼动画编辑器就是cocosStudio和spine了。但是就我的感受,2款编辑器中spine可以说是完爆ccs的骨骼动画部分,不仅因为spine容易上手,并且它提供了mesh,通常来说一张纹理只有4个顶点,左下右下左上右上,但是有了mesh,我们可以抓取这个图片,并设置大量的顶点给它,之后就能通过对顶点的设置完成图片的拉伸形变,比如乳摇功能。spine中30帧为1s,最新版中也提供了IK,可以将骨骼固定,做动作。具体的编辑我就不说了,主要说一下运行库。首先提供spine的最新运行库,当然这不是官方的,里面封装了ffd,是我自己修改过并添加了ffd代码,采用newSkeletonAnimation区别原先的skeletonAnimation具体点击:&&其中要注意的几个地方:1.&&1.8版本以上的atlas做了修改 在第二行添加了size 所以只要删除size这一行即可,
2. 动作制作的时候如果层级有发生改变或者切换了skin,slot,请K帧一下,修改的部分:draworder和bone,一般首尾都K一下就行了。3.至于.skel的binary文件,是spine本身就提供的二进制文件,性能必然高于json,本人目前正在修改完善spine runtime的binary(因为官方也不提供,完成起来慢了点,以后或许会放出)。4.newskeletonanimation在create时候最后一个参数scale别忘了。说一下runtime中常用的一些方法:skeletonNode = NEWSkeletonAnimation::createWithFile(&spineboy.json&, &spineboy.atlas&, 0.6f);//创建动作,最后的参数为scale.[html]
& && & skeletonNode-&startListener = [this] (int trackIndex) {//设置动作开始检测的监听器&&spTrackEntry* entry = spAnimationState_getCurrent(skeletonNode-&state, trackIndex);//获得当前动作的状态信息&&const char* animationName = (entry && entry-&animation) ? entry-&animation-&name : 0;&&& & log(&%d start: %s&, trackIndex, animationName);&&};&&skeletonNode-&endListener = [] (int trackIndex) {//同理,结束动作监听&&& & log(&%d end&, trackIndex);&&};&&skeletonNode-&completeListener = [] (int trackIndex, int loopCount) {//同理,完成动作监听&&& & log(&%d complete: %d&, trackIndex, loopCount);&&};&&skeletonNode-&eventListener = [] (int trackIndex, spEvent* event) {//同理,事件监听,在spine中编辑好event导出&&& & log(&%d event: %s, %d, %f, %s&, trackIndex, event-&data-&name, event-&intValue, event-&floatValue, event-&stringValue);&&};&&&&skeletonNode-&setMix(&walk&, &jump&, 0.2f);//协调动作&&skeletonNode-&setMix(&jump&, &run&, 0.2f);&&skeletonNode-&setAnimation(0, &walk&, true);//设置动作,可用多个set进行动作混合&&spTrackEntry* jumpEntry = skeletonNode-&addAnimation(0, &jump&, false, 3);//添加动作,在上个动作直接玩之后,之后为循环参数和delay&&skeletonNode-&addAnimation(0, &run&, true);&&&&skeletonNode-&setStartListener(jumpEntry, [] (int trackIndex) {&&& & log(&jumped!&);&&});&/span&&&
skeletonNode-&timeScale = 0.3f;//动作间隔&&skeletonNode-&debugBones =//debug模式&&skeletonNode-&update(0);//更新动作&&spBone* root=skeletonNode-&findBone(&root&);//找到name为root的骨骼,同理&&通过 findslot 可以找到名字为name的slot&&
顺便吐糟一下cocos2dx 官方,虽说cocosstduio是亲儿子吧,但是也不能不管spine啊,spine的ffd一直愣是没加上去,逼得我自己改过来- =!
如何让别人关注你?
本楼回复(<span id="dp_count_)
如何让别人关注你?
学到了学到了
本楼回复(<span id="dp_count_)
如何让别人关注你?
好想求一个cocos2d-js用了骨骼动画的实例~~~
本楼回复(<span id="dp_count_)
如何让别人关注你?
本楼回复(<span id="dp_count_)
如何让别人关注你?
Powered by

我要回帖

更多关于 spine mesh 功能 的文章

 

随机推荐