两种方法
- 制作带有空插槽的spine动画文件,找到挂载空插槽的目标slot
getNodeForSlot
,在其挂载node上添加想要的元素addChild
- 直接使用外部texture替换相应挂载texture
setSlotAttachment
,但是要求目标texture与原texture大小要一致
代码如下:
#include "cocos\editor-support\spine\spine-cocos2dx.h"
#include "cocos\editor-support\spine\SkeletonBatch.h"
#include "cocos\editor-support\spine\AttachmentVertices.h"
#include "OSDLLDefine.h"
using namespace std;
using namespace cocos2d;
using namespace spine;
struct spSkeleton;
class MYSpine: public spine::SkeletonAnimation
{
public:
~MYSpine() {
}
MYSpine();
static MYSpine* create(const std::string& skeletonDataFile, const std::string& atlasFile);
//获取slot插槽节点,可以在该节点上添加自己新建的node
cocos2d::CCNodeRGBA* getNodeForSlot(string slotName);
//使用外部图片资源设置slot节点上挂载spAttachment
void setSlotAttachment(const std::string &slotName, Texture2D *texture);
private:
struct sSlotNode
{
spSlot* slot;
cocos2d::CCNodeRGBA* node;
};
//重写父类渲染逻辑
virtual void draw(Renderer* renderer, const Mat4& transform, uint32_t transformFlags);
typedef std::map<string, sSlotNode> SlotNodeMap;
typedef SlotNodeMap::iterator SlotNodeIter;
SlotNodeMap m_slotNodes;
};
#include "MYSpine.h"
#include "SkeletonBatch.h"
#include "SkeletonTwoColorBatch.h"
#include "extension.h"
MYSpine::MYSpine()
:SkeletonAnimation()
{
}
MYSpine* MYSpine::create(const std::string& skeletonDataFile, const std::string& atlasFile)
{
GCSpine* node = new MYSpine();
spAtlas* atlas = spAtlas_createFromFile(atlasFile.c_str(), 0);
node->initWithJsonFile(skeletonDataFile, atlas, 1.0);
node->autorelease();
return node;
}
cocos2d::CCNodeRGBA* MYSpine::getNodeForSlot(std::string slotName) {
SlotNodeIter iter = m_slotNodes.find(slotName);
if (iter != m_slotNodes.end()) {
sSlotNode& slot_node = iter->second;
return slot_node.node;
}
else {
spSlot* slot = findSlot(slotName);
if (slot != NULL) {
CCNodeRGBA* node = new CCNodeRGBA();
if (node->init()) {
node->autorelease();
}
node->setPosition(0, 0);
this->addChild(node);
sSlotNode slot_node;
slot_node.slot = slot;
slot_node.node = node;
m_slotNodes.insert(SlotNodeMap::value_type(slotName, slot_node));
return node;
}
else {
return NULL;
}
}
}
void MYSpine::draw(Renderer * renderer, const Mat4 & transform, uint32_t transformFlags)
{
SkeletonBatch* batch = SkeletonBatch::getInstance();
SkeletonTwoColorBatch* twoColorBatch = SkeletonTwoColorBatch::getInstance();
bool isTwoColorTint = this->isTwoColorTint();
if (_effect) _effect->begin(_effect, _skeleton);
Color4F nodeColor;
nodeColor.r = getDisplayedColor().r / (float)255;
nodeColor.g = getDisplayedColor().g / (float)255;
nodeColor.b = getDisplayedColor().b / (float)255;
nodeColor.a = getDisplayedOpacity() / (float)255;
Color4F color;
Color4F darkColor;
AttachmentVertices* attachmentVertices = nullptr;
TwoColorTrianglesCommand* lastTwoColorTrianglesCommand = nullptr;
for (int i = 0, n = _skeleton->slotsCount; i < n; ++i) {
spSlot* slot = _skeleton->drawOrder[i];
if (!slot->attachment) {
spSkeletonClipping_clipEnd(_clipper, slot);
continue;
}
cocos2d::TrianglesCommand::Triangles triangles;
TwoColorTriangles trianglesTwoColor;
switch (slot->attachment->type) {
case SP_ATTACHMENT_REGION: {
spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
attachmentVertices = getAttachmentVertices(attachment);
if (!isTwoColorTint) {
triangles.indices = attachmentVertices->_triangles->indices;
triangles.indexCount = attachmentVertices->_triangles->indexCount;
triangles.verts = batch->allocateVertices(attachmentVertices->_triangles->vertCount);
triangles.vertCount = attachmentVertices->_triangles->vertCount;
memcpy(triangles.verts, attachmentVertices->_triangles->verts, sizeof(cocos2d::V3F_C4B_T2F) * attachmentVertices->_triangles->vertCount);
spRegionAttachment_computeWorldVertices(attachment, slot->bone, (float*)triangles.verts, 0, 6);
}
else {
trianglesTwoColor.indices = attachmentVertices->_triangles->indices;
trianglesTwoColor.indexCount = attachmentVertices->_triangles->indexCount;
trianglesTwoColor.verts = twoColorBatch->allocateVertices(attachmentVertices->_triangles->vertCount);
trianglesTwoColor.vertCount = attachmentVertices->_triangles->vertCount;
for (int i = 0; i < trianglesTwoColor.vertCount; i++) {
trianglesTwoColor.verts[i].texCoords = attachmentVertices->_triangles->verts[i].texCoords;
}
spRegionAttachment_computeWorldVertices(attachment, slot->bone, (float*)trianglesTwoColor.verts, 0, 7);
}
color.r = attachment->color.r;
color.g = attachment->color.g;
color.b = attachment->color.b;
color.a = attachment->color.a;
break;
}
case SP_ATTACHMENT_MESH: {
spMeshAttachment* attachment = (spMeshAttachment*)slot