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实现预加载图片的方法及优缺点分析
预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画 廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发 ...
随机推荐
- 领域驱动设计业务框架DMVP
DMVP,全称DDD-MVP,是基于领域驱动设计(DDD)搭建的业务框架,整体设计符合DDD领域模型的规范,业务上达成了领域模型和代码的一一映射,技术上达成了高内聚低耦合的架构设计,开发人员不需要关注 ...
- PJzhang:搜索引擎高级语法与渗透测试
猫宁!!! 参考链接: https://www.freebuf.com/articles/network/169601.html https://www.jianshu.com/p/f8062e2cc ...
- linux 之基本命令学习总结
前言:从今天开始写这系列linux博客了(是学习刘遄老师的<linux就该这么学>),视频学习的资源可以在b站上找到:https://www.bilibili.com/video/av45 ...
- 3分钟简单了解 prototype 和 __proto__
关于prototype 1. 所有的函数都会有一个prototype属性,属性值是一个普通对象: 2. 当我们去new一个构造函数的实例时,构造函数的原型对象(prototype)会被赋值给它实例的[ ...
- [WebShow系列] 倒计时展示相关问题
WebShow内置了倒计时功能. 后台参数维护: 倒计时参数说明: 倒计时基准时间设置(秒数):假设设置为90,也就是从1分30秒开始倒计时,同时有开始提示音. 倒计时提示1剩余秒数:假设设置为30, ...
- 运用html常用标签和css定位等学做模仿百度导航页面
导航部分文字链接,鼠标触碰变颜色,除百度logo引用图片外,其它均代码编写.注释部分是一开始用的百度一下截图做的按钮,后来用div填充颜色写了一个按钮.效果图如下. HTML代码如下: <!DO ...
- II play with GG(思维规律)
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format: %lld 题目描述 IG won the S champion ...
- criteria用法
Criteria Query通过面向对象化的设计,将数据查询条件封装为一个对象.简单来讲,Criteria Query可以看作是传统SQL的对象化表示,如: Java代码 Criteria cri ...
- SpringCloud 分布式配置中心
SpringCloud 分布式配置中心 服务端 创建工程并完善结构 国际惯例,把maven工程创建完善 pom.xml <?xml version="1.0" encodin ...
- RHEL6.4 安装 highpoint RocketRAID 2720 阵列卡驱动
step1:下载驱动程序. http://www.highpoint-tech.com/USA_new/series_rr272x_configuration.htm step2:上传驱动程序至服务器 ...