Cocos2d-lua中缓存骨骼动画

在cocos2d-lua中,当使用craete方法同时创建加载多个骨骼动画时,会发生卡顿。因为在每次调用craete方法时,都需要先生成一次skeletonData数据。如果可以将skeletonData数据事先加入到缓存中,然后直接用缓存的skeletonData数据去生成骨骼动画,就可以优化卡顿的问题。

先看看如何实现对skeletonData数据进行缓存。

缓存skeletonData数据

实现将资源数据加入缓存的lua方法如下:

--将skeletonData数据加入缓存
function addSkeletonDataToCache(cacheName,jsonStr,atlasStr)
	--参数是否正确
	if not cacheName or not jsonStr or not atlasStr then
		return;
	end
	
	--是否已经存在于缓存中
	if sp.SkeletonAnimation:isExistSkeletonDataInCache(cacheName) then
		return;
	end
	
	--资源是否存在
	if not cc.FileUtils:getInstance():isFileExist(jsonStr) or not cc.FileUtils:getInstance():isFileExist(atlasStr) then
		return;
	end
	
	sp.SkeletonAnimation:readSkeletonDataToCache(cacheName, jsonStr, atlasStr);
end

--将skeletonData数据从缓存中移除
function removeSkeletonDataFromCache(cacheName)
	--是否存在于缓存中
	if not sp.SkeletonAnimation:isExistSkeletonDataInCache(cacheName) then
		return;
	end
	
	sp.SkeletonAnimation:removeSkeletonData(cacheName)
end

可以在预加载资源的时候,通过调用上述实现的addSkeletonDataToCache方法将骨骼动画数据加入缓存中。
例如:

addSkeletonDataToCache(“testCacheName”, "test.json", "test.atlas");

在需要使用的时候,通过以下方式调用(使用缓存时定义的名字)。

local testAnimation = sp.SkeletonAnimation:createFromCache("testCacheName");
testAnimation:setAnimation(0, "test", true);
self:addChild(testAnimation);

在不需要的时候,通过removeSkeletonDataFromCache将其从缓存中移除。

-------------------------------------------------以下是分析部分-------------------------------------------------

create方法

在cocos2d-lua中,通常情况下,我们使用create方法创建骨骼动画。
例如:

local testAnimation = sp.SkeletonAnimation:create("test.json", "test.atlas");
testAnimation:setAnimation(0, "test", true);
self:addChild(testAnimation);

来看一下lua中注册的create方法如下。

tolua_function(L, "create", lua_cocos2dx_CCSkeletonAnimation_createWithFile);

可以发现,create方法其实就是SkeletonAnimation类中的createWithFile方法,查看createWithFile方法源码如下:

SkeletonAnimation* SkeletonAnimation::createWithFile (const std::string& skeletonDataFile, spAtlas* atlas, float scale) {
	SkeletonAnimation* node = new SkeletonAnimation(skeletonDataFile, atlas, scale);
	node->autorelease();
	return node;
}

SkeletonAnimation* SkeletonAnimation::createWithFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale) {
	SkeletonAnimation* node = new SkeletonAnimation(skeletonDataFile, atlasFile, scale);
	node->autorelease();
	return node;
}

可以看到,createWithFile可以接受两种形式的参数,上述例子中使用的是所示代码中的第二种形式,所以简单看一下第二种方式的源码实现流程。

SkeletonAnimation::SkeletonAnimation (const std::string& skeletonDataFile, const std::string& atlasFile, float scale)
		: SkeletonRenderer(skeletonDataFile, atlasFile, scale) {
	initialize();
}

SkeletonRenderer::SkeletonRenderer (const std::string& skeletonDataFile, const std::string& atlasFile, float scale)
		: _atlas(0), _debugSlots(false), _debugBones(false), _timeScale(1) {
	initWithFile(skeletonDataFile, atlasFile, scale);
}

void SkeletonRenderer::initWithFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale) {
	_atlas = spAtlas_createFromFile(atlasFile.c_str(), 0);
	CCASSERT(_atlas, "Error reading atlas file.");

	spSkeletonJson* json = spSkeletonJson_create(_atlas);
	json->scale = scale;
	spSkeletonData* skeletonData = spSkeletonJson_readSkeletonDataFile(json, skeletonDataFile.c_str());
	CCASSERT(skeletonData, json->error ? json->error : "Error reading skeleton data file.");
	spSkeletonJson_dispose(json);

	setSkeletonData(skeletonData, true);

	initialize();
}

createFromCache

在lua源码中,除了create方法外,还可以看到一个创建骨骼动画的方法,那就是createFromCache

tolua_function(tolua_S,"createFromCache", lua_cocos2dx_spine_SkeletonAnimation_createFromCache);

来看一下它的C++实现:

SkeletonAnimation* SkeletonAnimation::createFromCache(const std::string& skeletonDataKeyName)
{
	if (spSkeletonData* skeleton_data = getSkeletonDataFromCache(skeletonDataKeyName,true)){		
		SkeletonAnimation* node = new SkeletonAnimation(skeleton_data, false);
		node->skeletonDataKeyName = skeletonDataKeyName;
		node->autorelease();
		return node;
	}

	return nullptr;
}

SkeletonAnimation::SkeletonAnimation (spSkeletonData *skeletonData, bool ownsSkeletonData)
		: SkeletonRenderer(skeletonData, ownsSkeletonData) {
	initialize();
}

SkeletonRenderer::SkeletonRenderer (spSkeletonData *skeletonData, bool ownsSkeletonData)
	: _atlas(0), _debugSlots(false), _debugBones(false), _timeScale(1) {
	initWithData(skeletonData, ownsSkeletonData);
}

void SkeletonRenderer::initWithData (spSkeletonData* skeletonData, bool ownsSkeletonData) {
	setSkeletonData(skeletonData, ownsSkeletonData);

	initialize();
}

与之前的create方法对比可以发现,createFromCache是直接使用skeletonData来初始化骨骼动画的,省去了中间创建skeletonData的过程,所以效率会高很多。而create方法在每次调用的时候,都需要先生成skeletonData数据。

你可能感兴趣的:(Cocos2d-lua中缓存骨骼动画)