您的位置:首页 > 其它

异步加载资源的loading界面

2016-03-21 15:43 483 查看
可异步加载小图,大图,armature,音效

.h文件如下

class LoadingLayer : public cocos2d::Layer{
public:
// 构造和析构函数
LoadingLayer();
virtual ~LoadingLayer();
CREATE_FUNC(LoadingLayer);

virtual bool init();

/**
*  设置要预加载的文件(文件中包含小图、大图等资源。 这里文件格式为json)
*
*  @param fileName 路径加文件名
*  @param layer 节点要加的父节点创建一个特效
*/
void setConfig(const char *fileName);

/**
*  启动加载资源(判断资源路径是否存在,计算总共要加载的资源的数量)
*/
void start();
private:
/**
*  屏幕适配
*/
void doLayout(float delay);

/**
*  主线程中更新加载数量的计时器
*/
void myUpdate(float delay);

/**
*  异步加载小图的回调
*/
void imageAsyncCallback(cocos2d::Texture2D *texture);

/**
*  异步加载大图的回调
*/
void plistImageAsyncCallback(cocos2d::Texture2D* texture);

/**
*  异步加载jsonExport的回调
*/
void jsonAsyncCallback(float f);

/**
*  回调加载资源
*/
void doLoad();
public:
typedef std::function<void()> LoadingCallback; // 定义一种类型LoadingCallback(返回值为空的回调方法)

LoadingCallback onBegan; // 启动loading界面时需要进行的回调
LoadingCallback onUpdate; // 在加载过程中需要进行的回调
LoadingCallback onFinish; // 全部加载完毕后需要进行的回调

private:
cocos2d::ui::Node* m_rootNode; // 当前场景的节点
cocos2d::ui::Text* m_loadingNum; // 显示进度数量的控件
cocos2d::ui::LoadingBar* m_loadingBar; // 显示进度的进度条
rapidjson::Document loadJson; // 包含要预加载的小图、大图等资源的json文件

// 因为加载大图需要plist和png两个文件,所以定义一个类型
struct plistStruct
{
std::string plist;
std::string png;
};

std::queue<std::string> pngQueue; // 存放png的队列
std::queue<plistStruct> plistQueue; // 存放plist的队列
std::queue<std::string> armatureQueue; // 存放exportJson的队列
std::queue<std::string> audioQueue; // 存放音效的队列

int totalCount;  // 所有要加载的资源
int count; // 现已加载的资源
float percent; // 已加载的资源与全部要加载的资源的百分比
float showPercent; // 进度条上显示的百分比
};


.cpp文件如下

// 构造函数
LoadingLayer::LoadingLayer() :
onBegan(nullptr), // 初始化
onFinish(nullptr),
onUpdate(nullptr),
percent(0.0f),
showPercent(0.0f),
totalCount(0),
count(0)
{
}

析构函数
LoadingLayer::~LoadingLayer()
{

}

// 初始化
bool LoadingLayer::init(){
if (!Layer::init())
{
return false;
}
// 创建loading界面的节点
m_rootNode = CSLoader::createNode("CSD/LayerLoginLoading/LoadingLayer.csb");
addChild(m_rootNode );

// 获取控件并进行初始化设置
m_loadingNum = (Text*)Helper::seekWidgetByName((Widget*)m_rootNode , "loadingnumber_Lab");
m_loadingBar = (LoadingBar*)Helper::seekWidgetByName((Widget*)m_rootNode , "loadingBar");

m_loadingBar->setPercent(0);

m_loadingNum->setString(Value(showPercent).asString());

this->setSwallowEnable(true); // 设置当前层是否吞噬事件(本人使用的框架中有用到,可以忽略这段代码)

Director::getInstance()->getTextureCache()->removeUnusedTextures(); // 移除不使用的纹理
SpriteFrameCache::getInstance()->removeUnusedSpriteFrames(); // 移除不使用的缓存

SAE->stopAllEffects(); // 停止所有的音效
SAE->stopBackgroundMusic(false); // 停止所有的背景音乐

doLayout(); // 屏幕适配
return true;
}

// 屏幕适配
void LoadingLayer::doLayout()
{
auto size = Director::getInstance()->getVisibleSize();
m_rootNode->setContentSize(size);
ui::Helper::doLayout(m_rootNode);
}

// 设置预加载的文件
void LoadingLayer::setConfig(const char *fileName)
{
LsTools::readJsonWithFile(fileName, loadJson); // 将json文件读出来, 保存在loadJson对象中
}

// 启动加载资源
void LoadingLayer::start(){
for (unsigned int i = 0; i < loadJson["png"].Size(); i++)
{
if (!FileUtils::getInstance()->isFileExist(loadJson["png"][i].GetString())){
std::string tStr = loadJson["png"][i].GetString();

cocos2d::MessageBox("file is not exist : %s", tStr.c_str()); // 如果路径下的小图不存在,则弹出一个警告框
continue;
}
pngQueue.push(loadJson["png"][i].GetString()); // 遍历将所有小图的名字都添加到队列中
}
for (unsigned int i = 0; i < loadJson["plist"].Size(); i++)
{
if (!FileUtils::getInstance()->isFileExist(loadJson["plist"][i][0].GetString())){
std::string tStr = loadJson["plist"][i][0].GetString();

cocos2d::MessageBox("file is not exist : %s", tStr.c_str());// 如果路径下的大图不存在,则弹出一个警告框
continue;
}
plistStruct res;
res.png = loadJson["plist"][i][0].GetString();
res.plist = loadJson["plist"][i][1].GetString();
plistQueue.push(res); // 遍历将所有大图的名字都添加到队列中
}
for (unsigned int i = 0; i < loadJson["armature"].Size(); i++)
{
if (!FileUtils::getInstance()->isFileExist(loadJson["armature"][i].GetString())){
std::string tStr = loadJson["armature"][i].GetString();

cocos2d::MessageBox("file is not exist : %s", tStr.c_str());// 如果路径下的exportJson文件不存在,则弹出一个警告框
continue;
}

armatureQueue.push(loadJson["armature"][i].GetString());
}
for (unsigned int i = 0;i < loadJson["effectAudio"].Size(); i++)
{
if (!FileUtils::getInstance()->isFileExist(loadJson["effectAudio"][i].GetString())){
std::string tStr = loadJson["effectAudio"][i].GetString();

cocos2d::MessageBox("file is not exist : %s", tStr.c_str());// 如果路径下的音效文件不存在,则弹出一个警告框
continue;
}

audioQueue.push(loadJson["effectAudio"][i].GetString());
}

if (onBegan)
onBegan(); // 执行加载资源前的回调

totalCount = loadJson["png"].Size() + loadJson["plist"].Size() + loadJson["armature"].Size() + loadJson["effectAudio"].Size(); // 获得所有要加载的资源的数量
count = 0;
doLoad(); // 开始加载资源

this->schedule(CC_SCHEDULE_SELECTOR(LoadingLayer::myUpdate)); // 开启显示加载数量的计时器
}

// 回调加载资源
void LoadingLayer::doLoad(){
if (pngQueue.size() > 0){
Director::getInstance()->getTextureCache()->addImageAsync(pngQueue.front(),
CC_CALLBACK_1(LoadingLayer::imageAsyncCallback, this)); // 异步加载小图
}
else if (plistQueue.size() > 0){
Director::getInstance()->getTextureCache()->addImageAsync(plistQueue.front().png,
CC_CALLBACK_1(LoadingLayer::plistImageAsyncCallback, this)); // 异步加载大图
}
else if (armatureQueue.size() > 0){
ArmatureDataManager::getInstance()->addArmatureFileInfoAsync(armatureQueue.front(),
this, CC_SCHEDULE_SELECTOR(LoadingLayer::jsonAsyncCallback)); // 异步加载exportJson文件
}
else if(audioQueue.size() > 0){ // 一次性把所有的音效加入到缓存,因为该接口没有回调方法
int tSize = audioQueue.size();
for (int i = 0; i < tSize; i++)
{
SAE->preloadEffect(audioQueue.front().c_str());
count++;
}

}
count++;
}

void LoadingLayer::imageAsyncCallback(cocos2d::Texture2D *texture)
{           //加载小图
pngQueue.pop(); // 将第一个小图名字移出队列

doLoad(); // 又重新回调加载资源
}

void LoadingLayer::plistImageAsyncCallback(cocos2d::Texture2D* texture)
{           //加载大图
SpriteFrameCache::getInstance()->addSpriteFramesWithFile(plistQueue.front().plist, texture); // texture 为大图对应的小图的纹理
plistQueue.pop(); // 将第一个大图名字移出队列
doLoad(); // 又重新回调加载资源
}

void LoadingLayer::jsonAsyncCallback(float f)
{       // 加载jsonExport
armatureQueue.pop(); 将第一个exportJson名字移出队列
doLoad(); // 又重新回调加载资源
}

// 主线程中更新加载数量的计时器
void LoadingLayer::myUpdate(float delay){
percent = count / totalCount * 100; // 化作百分比
if (count > totalCount && showPercent >= 100.0f)
{   // 当已加载的资源大于总共要加载的资源,并且显示的百分比大于等于100时关闭计时器
unschedule(CC_SCHEDULE_SELECTOR(LoadingLayer::myUpdate));
if (onFinish)
{
onFinish(); // 执行加载完资源的回调
}
close(); (本人使用的框架中有用到,可以忽略这段代码,相当于removeFromParent方法,把当前层从节点树种移除)
return;
}

if (showPercent > 100.0f)
{
showPercent = 100.0f;
}
else if (showPercent < percent){
showPercent++;
}
m_loadingNum->setString(Value((int)showPercent).asString() + "%");
m_loadingBar->setPercent(showPercent);
m_heroAnimation->setPositionX(m_loadingBar->getContentSize().width * (showPercent / 100));
}


以上就是Loading类的所有代码, 除去构造析构函数,Loading类只有9个方法,12个变量。

方法:

init() 初始化。

setConfig() 设置要预加载的文件。

start() 启动加载资源。

doLayout() 屏幕适配。

imageAsyncCallback() 异步加载小图的回调。

jsonAsyncCallback() 异步加载jsonExport的回调。

doLoad() 回调加载资源。

变量:

m_rootNode 当前场景的节点。

m_loadingNum 显示进度数量的控件。

m_loadingBar 显示进度的进度条。

loadJson 包含要预加载的小图、大图等资源的json文件。

plistQueue 存放plist的队列。

audioQueue 存放音效的队列。

count 现已加载的资源。

showPercent 进度条上显示的百分比。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: