Spine使用外部图片动画换肤

两种方法

  1. 制作带有空插槽的spine动画文件,找到挂载空插槽的目标slotgetNodeForSlot,在其挂载node上添加想要的元素addChild
  2. 直接使用外部texture替换相应挂载texturesetSlotAttachment,但是要求目标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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Android上使用Spine动画,您需要执行以下步骤: 1. 下载和安装Spine软件包并创建您的动画。 2. 在您的Android项目中添加Spine库。您可以使用Gradle或手动添加库。 3. 在您的布局文件中添加Spine视图。 4. 在您的Java代码中加载并控制Spine动画。您可以使用Spine的Java API来处理所有加载和控制操作。 以下是一个使用Spine的简单示例: 1. 添加Spine库 在您的build.gradle文件中添加以下依赖项: ``` dependencies { implementation 'com.esotericsoftware.spine:spine-libgdx:3.8.99.1' } ``` 2. 添加Spine视图 在您的布局文件中添加一个Spine视图: ``` <com.esotericsoftware.spine.SkeletonView android:id="@+id/skeleton_view" android:layout_width="match_parent" android:layout_height="match_parent"/> ``` 3. 加载和控制Spine动画 在您的Java代码中,可以使用以下代码加载Spine动画: ``` SkeletonDataLoader loader = new SkeletonDataLoader(new AssetManager(assetManager)); SkeletonData skeletonData = loader.load("path/to/your/skeleton.json", "path/to/your/skeleton.atlas"); SkeletonAnimation skeletonAnimation = new SkeletonAnimation(skeletonData); // Add the skeleton animation to your Spine view SkeletonView skeletonView = findViewById(R.id.skeleton_view); skeletonView.setSkeletonAnimation(skeletonAnimation); ``` 然后,您可以使用SkeletonAnimation对象来控制Spine动画,例如: ``` // Play the animation skeletonAnimation.setAnimation(0, "your_animation_name", true); // Pause the animation skeletonAnimation.getState().getTimeScale() = 0f; // Resume the animation skeletonAnimation.getState().getTimeScale() = 1f; ``` 以上是一个简单的使用Spine动画的示例。您可以根据您的需求进行更高级的控制和自定义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值