cocos2x (c++/lua) spine 文件的预加载

在之前,笔者写过一编博客,通过lua在加载场景加载spineAnimation动画精灵,保存在table中,然后在游戏中创建动画精灵时,提取加载好的spineAnimaiton中的

spSkeletonData来创建spineAnimation,但后来笔者发现重复创建spineAnimation时,全部相同spSkeletonData会重用同一个spSkeletonData,以下是spSkeletonData拷贝方法的源代码:

spSkeleton* spSkeleton_create (spSkeletonData* data) {

int i, ii;

_spSkeleton* internal = NEW(_spSkeleton);

spSkeleton* self = SUPER(internal);

CONST_CAST(spSkeletonData*, self->data) = data;

self->bonesCount = self->data->bonesCount;

self->bones = MALLOC(spBone*, self->bonesCount);

for (i = 0; i < self->bonesCount; ++i) {

spBoneData* boneData = self->data->bones[i];

spBone* parent = 0;

if (boneData->parent) {

/* Find parent bone. */

for (ii = 0; ii < self->bonesCount; ++ii) {

if (data->bones[ii] == boneData->parent) {

parent = self->bones[ii];

break;

}

}

}

self->bones[i] = spBone_create(boneData, self, parent);

}

CONST_CAST(spBone*, self->root) = self->bones[0];

self->slotsCount = data->slotsCount;

self->slots = MALLOC(spSlot*, self->slotsCount);

for (i = 0; i < self->slotsCount; ++i) {

spSlotData *slotData = data->slots[i];

/* Find bone for the slotData‘s boneData. */

spBone* bone = 0;

for (ii = 0; ii < self->bonesCount; ++ii) {

if (data->bones[ii] == slotData->boneData) {

bone = self->bones[ii];

break;

}

}

self->slots[i] = spSlot_create(slotData, bone);

}

self->drawOrder = MALLOC(spSlot*, self->slotsCount);

memcpy(self->drawOrder, self->slots, sizeof(spSlot*) * self->slotsCount);

self->r = 1;

self->g = 1;

self->b = 1;

self->a = 1;

self->ikConstraintsCount = data->ikConstraintsCount;

self->ikConstraints = MALLOC(spIkConstraint*, self->ikConstraintsCount);

for (i = 0; i < self->data->ikConstraintsCount; ++i)

self->ikConstraints[i] = spIkConstraint_create(self->data->ikConstraints[i], self);

spSkeleton_updateCache(self);

return self;

}

在拷贝当中,骨骼数据确实新开辟一个内存,拷贝了一份新的spSkeletonData,但是,由于spSkeletonData属于在table中保存的SkeletonAnimation中,受到SkeletonAnimation的影响,所以不能使用SkeletonAnimation中的spSkeletonData去创建另外一个SkeletonAnimation。

笔者也试过从lua中创建spSkeletonData数据,保存在table中,然后在游戏中传递spSkeletonData去创建SkeletonAnimation,

但在切换场景过程中,spSkeletonData会被释放掉,所以不能被复用。

后来笔者从c++入手,将spSkeletonData保存在c++静态的字典中,通过键值提取spSkeletonData去创建SkeletonAnimation,避免释放问题。

以下是实现方法:

//SpineAnimation_new.h

#include <stdio.h>

#include "cocos/editor-support/spine/SkeletonAnimation.h"

#include "cocos/editor-support/spine/spine.h"

#include "spine/SkeletonRenderer.h"

#include "cocos2d.h"

using namespace spine;

using namespace std;

class SpineAnimation_new:spine::SkeletonAnimation

{

public:

static SpineAnimation_new *createWithSkeletonData(spSkeletonData* skeletonData);

static SpineAnimation_new *createWithKey(const std::string& key);

virtual ~SpineAnimation_new();

spAnimationState* getState() {return SkeletonAnimation::getState();}

spSkeletonData* getSkeletonData()

{

spSkeletonData*skData =SkeletonRenderer::getSkeleton()->data;

return skData;

}

static spSkeletonData*loadSkeletonData(const std::string& atlasFile,const std::string& jsonFile,const std::string& key);

static map<const std::string,spSkeletonData*> skeletonDataMap;

static void clear();

private:

SpineAnimation_new(spSkeletonData*skeletonData);

SpineAnimation_new(const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 1);

};

#endif

//SpineAnimation_new.cpp

#include "SpineAnimation_new.h"

#include "cocos2d.h"

#include "cocos/scripting/lua-bindings/manual/cocos2d/LuaScriptHandlerMgr.h"

#include "CCLuaStack.h"

#include "CCLuaEngine.h"

USING_NS_CC;

map<const std::string,spSkeletonData*> SpineAnimation_new::skeletonDataMap;

SpineAnimation_new *SpineAnimation_new::createWithSkeletonData(spSkeletonData* skeletonData)

{

SpineAnimation_new* node = new (std::nothrow)SpineAnimation_new(skeletonData);

node->autorelease();

return node;

}

spSkeletonData*SpineAnimation_new::loadSkeletonData(const std::string& atlasFile,const std::string& jsonFile,const std::string& key)

{

spAtlas* atlas = spAtlas_createFromFile(atlasFile.c_str(), 0);

spSkeletonJson* json = spSkeletonJson_create(atlas);

json->scale = 1;

spSkeletonData* sd = spSkeletonJson_readSkeletonDataFile(json, jsonFile.c_str());

SpineAnimation_new::skeletonDataMap.insert(pair<const std::string,spSkeletonData*>(key,sd));

return sd;

}

SpineAnimation_new *SpineAnimation_new::createWithKey(const std::string& key)

{

map<const std::string,spSkeletonData*>::iterator iter = SpineAnimation_new::skeletonDataMap.find(key);

spSkeletonData* sd = iter->second;

SpineAnimation_new*sa = createWithSkeletonData(sd);

return sa;

}

SpineAnimation_new::~SpineAnimation_new()

{

ScriptHandlerMgr::getInstance()->removeObjectAllHandlers((void*)this);

}

SpineAnimation_new::SpineAnimation_new(spSkeletonData*skeletonData):

SkeletonAnimation(skeletonData)

{

}

SpineAnimation_new::SpineAnimation_new(const std::string& skeletonDataFile, const std::string& atlasFile, float scale):SkeletonAnimation(skeletonDataFile,atlasFile,scale)

{

}

void SpineAnimation_new::clear()

{

SpineAnimation_new::skeletonDataMap.clear();

}

(转载时请注明出处,from 博客园:HemJohn)

时间: 2024-08-10 20:42:49

cocos2x (c++/lua) spine 文件的预加载的相关文章

使用lua实现Spine动画的预加载

创建spine动画有两种方法,分别是createwithfile和createwithdata. createWithFile是通过加载动作数据马上进行创建,如果spine动画中的json文件大小超过100k时,会出现卡顿现象,如果动画文件偏小,可以使用这个方法来创建动画. createWithData是通过预加载,保存动画数据在spSkeletonData中,然后通过实现创建动画,这个方法可以使用在spine动画偏大的情况下使用. cocos2dx 自带的LuaSkeletonAnimatio

利用CSS、JavaScript及Ajax实现图片预加载的三大方法

原文:3 Ways to Preload Images with CSS, JavaScript, or Ajax 译文:利用CSS.JavaScript及Ajax实现图片预加载的三大方法 预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布,也可帮助用户在浏览你网站内容时获得更好的用户体验.本文将分享三个不同的预加载技术,来增强网站的性能与可用性.

利用CSS、JavaScript及Ajax实现图片预加载的三大方法及优缺点分析

预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布,也可帮助用户在浏览你网站内容时获得更好的用户体验.本文将分享三个不同的预加载技术,来增强网站的性能与可用性. 方法一:用CSS和JavaScript实现预加载 实现预加载图片有很多方法,包括使用CSS.JavaScript及两者的各种组合.这些技术可根据不同设计场景设计出相应的解决方案,十分高效.

关于图片预加载1

预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布,也可帮助用户在浏览你网站内容时获得更好的用户体验.本文将分享三个不同的预加载技术,来增强网站的性能与可用性. 方法一:用CSS和JavaScript实现预加载 实现预加载图片有很多方法,包括使用CSS.JavaScript及两者的各种组合.这些技术可根据不同设计场景设计出相应的解决方案,十分高效.

html预加载

预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据 很大比例的网站来说十分有利,它保证了图片快速.无缝地发布,也可帮助用户在浏览你网站内容时获得更好的用户体验.本文将分享三个不同的预加载技术,来增 强网站的性能与可用性. ? ? ? 方法一:用CSS和JavaScript实现预加载 ? ? ? 实现预加载图片有很多方法,包括使用CSS.JavaScript及两者的各种组合.这些技术可根据不同设计场景设计

使用CSS、JavaScript及Ajax实现图片预加载的方法详解 

预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布,也可帮助用户在浏览你网站内容时获得更好的用户体验.本文将分享使用CSS.JavaScript及Ajax实现图片预加载的三个不同技术,来增强网站的性能与可用性.一起来看看吧,希望对大家学习web前端有所帮助. 方法一:用CSS和JavaScript实现预加载 实现预加载图片有很多方法,包括使用CSS

详解HTML5中rel属性的prefetch预加载功能使用

在HTML5中,有个很有用但常被忽略的特性,就是预先加载(prefetch),它的原理是: 利用浏览器的空闲时间去先下载用户指定需要的内容,然后缓存起来,这样用户下次加载时,就直接从缓存中取出来,效率就快了. 举个例子说明:比如要预先加载某个页面,可以这样: XML/HTML Code <link rel="prefetch" href="http://www.example.com/"> <!-- Firefox --> 但如果是googl

HTML5 prefetch即预加载

原文地址 声明:此文带着自己的理解,不完全按原文翻译 prefetch 即预加载,在用户需要前我们就将所需的资源加载完毕. 有了浏览器缓存,为何还需要预加载? 用户可能是第一次访问网站,此时还无缓存 用户可能清空了缓存 缓存可能已经过期,资源将重新加载 用户访问的缓存文件可能不是最新的,需要重新加载 Chrome 的预加载技术 现在的 chrome 聪明到根据你的浏览记录,预测到你可能访问或搜索哪些网站,在你打开网站之前就加载好了一些资源了.举个栗子,当你在搜索框输入 "amaz" 时

实现图片预加载的三大方法

图片预加载的主要思路就是把稍后需要用到的图片悄悄的提前加载到本地,因为浏览器有缓存的原因,如果稍后用到这个url的图片了,浏览器会优先从本地缓存找该url对应的图片,如果图片没过期的话,就使用这个图片 如下是摘录具体的实现思路: <javascript图片预加载详解>图片的加载速度往往影响着网站整体的用户体验,尤其对于包含大量图片的网站.对图片进行预加载,不失为一个高效的解决方案.如何实现预加载?本文将例举利用CSS.JavaScript及ajax实现图片预加载的三大方法. Perishabl