当前位置: 首页 > 工具软件 > Spine Mobile > 使用案例 >

spine使用总结

蒙化
2023-12-01

因为项目的需要,cocos骨骼动画使用了spine,之前是使用cocosstudio,也不是ccs不好,毕竟spine是这方面的强项,不废话,直接上干货:
1.需要的头文件:

#include "spine/spine.h"
#include <spine/spine-cocos2dx.h>
using namespace spine;

2.接着创建spine动画

spine::SkeletonAnimation* spine=SkeletonAnimation::createWithFile(JsonFile,AtlasFile);

3.绑定一些回调:
当动画要开始播放的时候,回调格式为:

typedef std::function<void(int trackIndex)> StartListener;

绑定代码:

spine->setStartListener(CC_CALLBACK_1(Card::spineStar, this));

当动画跳出播放的时候,一般都是发生在动画切换的过程,回调格式:

typedef std::function<void(int trackIndex)> EndListener;

绑定代码:

spine->setStartListener(CC_CALLBACK_1(Card::spineEnd, this));

当前动画完成一个播放的时候,回调格式:

typedef std::function<void(int trackIndex, int loopCount)> CompleteListener;

回调代码:

spine->setStartListener(CC_CALLBACK_1(Card::spineComplete, this));

帧事件回调格式:

typedef std::function<void(int trackIndex, spEvent* event)> EventListener;

帧时间回调代码:需要说明的是,这个事件是由动作师在某个帧添加的,当执行到该动画的该帧的时候,就会触发回调。

spine->setStartListener(CC_CALLBACK_1(Card::spineEvent, this));

4.一个高级点的用法:
(1)设置动画切换过度时间,这样在动画过度的时候,有个缓冲时间,如果两个动作衔接点差别有点大,设置一下效果很好,这也是体现spine价值的地方。

spine->setMix(SPINE_MOVE_NAME, SPINE_IDLE_NAME, 0.1f);

(2)设置调试模式:
spine在调试模式,可以看到骨头的长度,骨点的位置:

sine->setDebugBonesEnabled(true);

也可以设置查看每个骨头绑定的图片的大小,会用矩形框显示出来:

spine->setDebugSlotsEnabled(true);

(3)设置缩放,设置播放速度:

spine->setScale(0.5f);

//播放速度暂时没有用到,以后补充
(4)获取某块骨头的位置:

spBone* bone = spine->findBone("hand");
float x = bone->worldX;
float y = bone->worldY;
float scale = spine->getScale();
Vec2 pos = Vec2(x,y)*scale;

需要说明的是:
findBone()返回的是结构体,当时我也迷惑怎么获取到位置信息,如果需要看为啥用这个,可以查看spineDraw函数,里面也是这么用的。
骨头的位置坐标是基于spine软件里面的(0,0)点,并且,是没有进行程序缩放的位置,所以最后一步要乘以scale。
(5)删除spine骨骼内存

void EffectAbstract::spineEnd(int trackIndex)
{
        this->removeFromParent();
}           

这段代码从理论上来说,spine的回调函数没有多少问题,但是实际运行到removeFromParent之后,程序就会立马崩溃,而且断点段在引擎spine代码中,这个问题纠结了一个上午,后来想到是不是我延时删除可不可以,试了之后,果然可以,不知道这算不算一个坑,反正是爬出来了,正确的代码:

void EffectAbstract::spineEnd(int trackIndex)
{
    CCDelayTime* time = CCDelayTime::create(1);
    CCCallFunc* callBack = CCCallFunc::create([=]()
    {
        this->removeFromParent();

    });
    this->runAction(CCSequence::create(time, callBack, nullptr));
}

(6) spine换装
局部换装用skine,修改底层代码:\cocos2d\cocos\editor-support\spine下面修改SkeletonAnimation.cpp,

//自己加一个局部换装的函数
bool SkeletonAnimation::replacementParts(const std::string& skinName, const std::string& attachmentName)
{
    if (skinName.empty())
    {
        return false;
    }

    spSkin *skin = spSkeletonData_findSkin(_skeleton->data, skinName.c_str());
    if (!skin) return false;
        for (int i = 0; i < _skeleton->slotsCount; ++i)
        {
            spSlot* slot = _skeleton->slots[i];
            if (strcmp(slot->data->name, attachmentName.c_str()) == 0)
            {
                spAttachment* attachment = spSkin_getAttachment(skin, i, slot->data->attachmentName);
                if (attachment) spSlot_setAttachment(slot, attachment);
                return true;
            }
        }

    return false;
    }

}

目前用到的就这么多,可能还要用到,后续更新。现在自己的游戏做的有点烂,要加把油了!

 类似资料: