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)
cocos2x (c++/lua) spine 文件的预加载的更多相关文章
- 使用lua实现Spine动画的预加载
创建spine动画有两种方法,分别是createwithfile和createwithdata. createWithFile是通过加载动作数据马上进行创建,如果spine动画中的json文件大小超过 ...
- vue-cli3 chainWebpack配置,去除打包后文件的预加载prefetch/preload(已解决)
//细节配置修改 chainWebpack: config => { console.log(config,'chainWebpack') // 移除 prefetch 插件 config.pl ...
- spine实现预加载(一)
前言 本文实现了spine动画的预加载,解决在战斗等大量加载spine动画的时候出现卡顿现象. 这里使用和修改三个类,直接修改的源码,当然你也可以继承LuaSkeletonAnimation,自己封装 ...
- Javascript图片预加载详解
预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...
- 利用CSS、JavaScript及Ajax实现图片预加载的三大方法
预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...
- 图片预加载和AJAX的图片预加载
利用js实现图片预加载,加载所需要图片的路径与名称即可,很容易实现,该方法尤其适用预加载大量的图片: <div class="hidden"> <script t ...
- 使用ajax预加载图片
使用Ajax 上面所给出的方法似乎不够酷,那现在来看一个使用Ajax实现图片预加载的方法.该方法利用DOM,不仅仅预加载图片,还会预加载CSS.JavaScript等相关的东西.使用Ajax,比直接使 ...
- 详解HTML5中rel属性的prefetch预加载功能使用
在HTML5中,有个很有用但常被忽略的特性,就是预先加载(prefetch),它的原理是: 利用浏览器的空闲时间去先下载用户指定需要的内容,然后缓存起来,这样用户下次加载时,就直接从缓存中取出来,效率 ...
- CSS和JavaScript以及Ajax实现预加载图片的方法及优缺点分析
预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画 廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发 ...
随机推荐
- 洛谷P2046 [NOI2010]海拔(最小割,平面图转对偶图)
传送门 不明白为什么大佬们一眼就看出这是最小割…… 所以总而言之这就是一个最小割我也不知道为什么 然后边数太多直接跑会炸,所以要把平面图转对偶图,然后跑一个最短路即可 至于建图……请看代码我实在无能为 ...
- 【微信小程序】开发实战 之 「数据缓存API」解析
每个小程序都可以有自己的本地缓存,可以通过 数据缓存的API 实现对本地缓存进行 设置.获取和清理.本地缓存最大为10M.localStorage是永久存储的,但我们不建议将关键信息都放在localS ...
- 查找库中的某个函数,grep命令的用法。
程序中调用了某个库中的函数,我想知道这个函数具体的作用,就必须去看这个库的源代码. 那么问题来了:如何从库中众多的.h文件中,得知我想要的函数在哪个文件里? 最后用grep命令成功解决. 具体用法:先 ...
- [bzoj 1758] 重建计划
bzoj 1758 重建计划 题意: 给定一棵有边权的树和两个数 \(L, R (L\leq R)\),求一条简单路径,使得这条路径经过的边数在 \(L, R\) 之间且路径经过的边的边权的平均值最大 ...
- Educational Codeforces Round 66 (Rated for Div. 2) A. From Hero to Zero
链接:https://codeforces.com/contest/1175/problem/A 题意: You are given an integer nn and an integer kk. ...
- 命令行 IRC 客户端 irssi 的基本操作
登录与退出 启动 irssi $ irssi 登陆 IRC 服务器/connect server port 修改昵称/nick nickname 直接带昵称登录指定的服务器$ irssi -c [se ...
- 常见的HTTP状态码说明
1.说明 HTTP服务器状态代码定义(Status Code Definitions) 做测试的时候,会产生比较多的HTTP错误,查看其错误,有超时的,链接不到图片的,连接不到服务器等等,很多人经常忘 ...
- .NET Core模块化
.NET Core模块化 源码地址 GitHub:https://github.com/iamoldli/NetModular 演示地址 地址:https://nm.iamoldli.com账户:ad ...
- fleet-运行一个全局的单元
运行一个全局的单元 正如前面所提到的,全局单元是有用的,用于在您的集群中的所有机器上运行一个单元.它不会比一个普通的单元差太多,而是一个新的x-fleet参数称为Global=true.这是一个示例单 ...
- strust2的10种type类型
<result-types> <result-type name="chain" class="com.opensymphony.xwork2.Acti ...