关于粒子系统的加载优化

2015年03月16日 11:13 0 点赞 0 评论 更新于 2017-05-09 17:21

在Cocos2d-x开发中,粒子系统是通过加载plist文件生成的。plist文件包含两部分重要内容:粒子系统属性和粒子纹理。然而,每次调用create方法时,都会对plist文件进行读取和解析。如果重复使用同一个粒子效果,这种调用方式会导致效率低下且存在冗余。为了优化这一过程,我们可以将粒子系统属性和粒子纹理分别抽取出来进行处理。

优化思路

  1. 预加载并全局保存粒子系统属性:避免每次使用粒子效果时都对plist文件进行读取操作,减少不必要的I/O开销。
  2. 处理粒子纹理:粒子纹理是可视的,并且可以进行纹理打包。加载粒子纹理的方式与加载普通图片相同。

本文将通过增加ParticleSystemQuad的接口,实现对粒子系统属性和纹理帧的直接载入,从而提高粒子系统的加载效率,并实现内存纹理的优化。

1. ParticleSystemQuad简介

ParticleSystemQuad继承自ParticleSystem,它不仅拥有父类的所有特性,还新增了一些实用的特性:

  • 粒子大小支持浮点数:可以更精确地控制粒子的大小。
  • 支持缩放:方便对粒子系统进行缩放操作,以适应不同的场景需求。
  • 支持选择:可根据具体需求选择不同的粒子效果。
  • 支持subrect:能够对纹理进行更灵活的裁剪和使用。
  • 支持批渲染:提高渲染效率,减少CPU和GPU之间的数据传输。

ParticleSystemQuad同时也是其他特效的父类。创建一个粒子系统的函数调用顺序为:Create → initWithFile → initWithDictionary。在initWithDictionary函数中,对粒子数据和纹理进行了读取和解析(有兴趣的读者可以直接查看源码)。

2. 优化方案

参考initWithDictionary的函数参数

static bool initWithDictionary(ValueMap& dictionary, const std::string& dirname);

设计优化接口

我们设计如下接口,当然,你也可以选择传入文件名:

static ParticleSystemQuad * create(ValueMap& valueMap, SpriteFrame *frame);
bool initWithValueMap(ValueMap &valueMap, SpriteFrame* frame);

源码实现

create函数

ParticleSystemQuad * ParticleSystemQuad::create( ValueMap& map, SpriteFrame *frame)
{
ParticleSystemQuad *ret = new ParticleSystemQuad();
if (ret && ret->initWithValueMap(map, frame))
{
ret->autorelease();
return ret;
}
CC_SAFE_DELETE(ret);
return ret;
}

initWithValueMap函数

bool ParticleSystemQuad::initWithValueMap(ValueMap &valueMap, SpriteFrame* frame)
{
std::string dirname = "";
bool ret = false;
unsigned char* buffer = nullptr;
unsigned char* deflated = nullptr;

do
{
int maxParticles = valueMap["maxParticles"].asInt();
// self, not super
if (this->initWithTotalParticles(maxParticles))
{
// Emitter name in particle designer 2.0
_configName = valueMap["configName"].asString();

// angle
_angle = valueMap["angle"].asFloat();
_angleVar = valueMap["angleVariance"].asFloat();

// duration
_duration = valueMap["duration"].asFloat();

// blend function
if (_configName.length() > 0)
{
_blendFunc.src = valueMap["blendFuncSource"].asFloat();
// 原代码此处未完整,可根据实际情况补充后续逻辑
}
}
} while (0);

return ret;
}

通过以上优化,我们可以避免重复读取plist文件,提高粒子系统的加载效率,同时优化内存纹理的使用。在实际开发中,你可以根据具体需求对代码进行进一步的调整和扩展。

作者信息

boke

boke

共发布了 3994 篇文章