功夫小子实践开发-资源异步加载及过渡场景的分析和实现

时间:2021-02-19 20:09:17

这一部分主要要学习的的点:

1.资源打包工具TexturePacker的使用

2.资源异步加载方法(TextureCache类)

3.多线程的运用



资源打包工具TexturePacker的使用

TexturePacker 图片打包工具讲解与使用并且批处理打多包以及资源加密


资源异步加载方法及多线程的运用介绍

Cocos2d-x教程-多线程与异步加载


具体代码如下:


全局参数类GlobalDefine.h中,我们用到了简单数据存储的Userdefault类,它可以用来存储一些简单的数据,比如声音的开启关闭,音效的开启关闭,最高分,金币数量的存储。具体见:cocos2d-x 之 简单数据存储——Userdefault


#ifndef __GlobalDefine__H__
#define __GlobalDefine__H__

#include "cocos2d.h"
#include "SimpleAudioEngine.h"

USING_NS_CC;
using namespace CocosDenshion;

#define WINSIZE Director::getInstance()->getWinSize()
//UserDefault用于保存数据的API
#define setIntToXML UserDefault::getInstance()->setIntegerForKey
#define setFloatToXML UserDefault::getInstance()->setFloatForKey
#define setBoolToXML UserDefault::getInstance()->setBoolForKey
#define getIntFromXML UserDefault::getInstance()->getIntegerForKey
#define getFloatFromXML UserDefault::getInstance()->getFloatForKey
#define getBoolFromXML UserDefault::getInstance()->getBoolForKey

#define SOUND_KEY "soundClose" // 背景音效
#define MUSIC_KEY "musicClose" // 背景音乐
#define SOUNDVOL "soundVolume" // 音效音量
#define MUSICVOL "musicVolume" // 音乐音量
#define EXP_KEY "heroCurrentExp" // 英雄当前经验
#define GAMELEVEL_KEY "gameLevel" // 当前关卡
#define HEROLEVEL_KEY "heroLevel" // 当前等级
#define HEROCOIN_KEY "heroCoin" // 英雄金币
#define HEROENERGY_KEY "heroEnergy" // 英雄体力
#define HEROHP_KEY "heroHP" // 英雄血量
#define HEROMP_KEY "heroMP" // 英雄能量
#define HEROAPOWER_KEY "heroAPower" // 英雄普攻伤害
#define HEROABILITY_KEY "heroAbility" // 英雄能力等级
#define SELECTGATE "selectGate" // 选择的关卡
#define GATEONE "gateOne" // 第一关
#define GATETWO "gateTwo" // 第二关
#define GATETHREE "gateThree" // 第三关
#define GAMEOVER "gameOver" // 游戏结束结果

#define aduioEngine SimpleAudioEngine::getInstance()


#define PLAYEFFECT if (getBoolFromXML(SOUND_KEY)) \
{\
aduioEngine->setEffectsVolume(getFloatFromXML(SOUNDVOL));\
aduioEngine->playEffect("Sound/button.wav");\
}

#endif

然后我们要做一个新的场景SplashLayer作为加载场景,界面只有一个logo,而背后会异步加载所有的图片以及多线程加载音乐和音效,最后切换场景


SplashLayer.h

#ifndef __SplashScene__H__
#define __SplashScene__H__

#include "cocos2d.h"
#include "SimpleAudioEngine.h"

USING_NS_CC;

class SplashLayer : public Layer
{
public:
virtual bool init();
static Scene* createScene();
CREATE_FUNC(SplashLayer);

private:
Sprite* logoSprite;
// 场景切换
void nextScene(float dt);
void loadingTextureCallBack(Texture2D * texture);
void loadingAudio();
void onExit();
// 初始化用户数据
void initUserData();
int m_iNumOfLoad;
std::thread* _loadingAudioThread;
};

#endif

SplashLayer.cpp

#include "SimpleAudioEngine.h"
#include "GlobalDefine.h"
#include "SplashLayer.h"
#include "StartLayer.h"

USING_NS_CC;
using namespace CocosDenshion;

Scene* SplashLayer::createScene()
{
Scene* splashScene = Scene::create();
SplashLayer* layer = SplashLayer::create();
splashScene->addChild(layer);
return splashScene;
}

bool SplashLayer::init()
{
if (!Layer::init())
{
return false;
}

// 初始化logo精灵
logoSprite = Sprite::create("logo.png");
logoSprite->setPosition(WINSIZE.width/2, WINSIZE.height/2);
this->addChild(logoSprite);

// 首次运行初始化用户数据
if (!getBoolFromXML("_IS_EXISTED"))
{
initUserData();
setBoolToXML("_IS_EXISTED", true);
UserDefault::getInstance()->flush();
}

setFloatToXML(SOUNDVOL, 0.80f);
setFloatToXML(MUSICVOL, 0.35f);
UserDefault::getInstance()->flush();

m_iNumOfLoad = 0;
// 图片和声音的异步加载
// 主界面
Director::getInstance()->getTextureCache()->addImageAsync("pnglist/startGame.png", CC_CALLBACK_1(SplashLayer::loadingTextureCallBack, this));
// 图籍
Director::getInstance()->getTextureCache()->addImageAsync("pnglist/gameLayer.png", CC_CALLBACK_1(SplashLayer::loadingTextureCallBack, this));
// 设置
Director::getInstance()->getTextureCache()->addImageAsync("pnglist/setLayer.png", CC_CALLBACK_1(SplashLayer::loadingTextureCallBack, this));
// 秘籍
Director::getInstance()->getTextureCache()->addImageAsync("pnglist/cheatsLayer.png", CC_CALLBACK_1(SplashLayer::loadingTextureCallBack, this));
// 选关
Director::getInstance()->getTextureCache()->addImageAsync("pnglist/gateMap.png", CC_CALLBACK_1(SplashLayer::loadingTextureCallBack, this));
// 暂停
Director::getInstance()->getTextureCache()->addImageAsync("pnglist/pauseLayer.png", CC_CALLBACK_1(SplashLayer::loadingTextureCallBack, this));

// 英雄
Director::getInstance()->getTextureCache()->addImageAsync("pnglist/hero.png", CC_CALLBACK_1(SplashLayer::loadingTextureCallBack, this));
Director::getInstance()->getTextureCache()->addImageAsync("pnglist/heroComobo.png", CC_CALLBACK_1(SplashLayer::loadingTextureCallBack, this));
Director::getInstance()->getTextureCache()->addImageAsync("pnglist/heroGun.png", CC_CALLBACK_1(SplashLayer::loadingTextureCallBack, this));

_loadingAudioThread = new std::thread(&SplashLayer::loadingAudio, this);

return true;
}

void SplashLayer::loadingTextureCallBack(Texture2D * texture)
{
switch (m_iNumOfLoad++)
{
case 0:
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("pnglist/startGame.plist", texture);
break;
case 1:
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("pnglist/gameLayer.plist", texture);
break;
case 2:
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("pnglist/setLayer.plist", texture);
break;
case 3:
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("pnglist/cheatsLayer.plist", texture);
break;
case 4:
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("pnglist/gateMap.plist", texture);
break;
case 5:
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("pnglist/pauseLayer.plist", texture);
break;
case 6:
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("pnglist/hero.plist", texture);
break;
case 7:
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("pnglist/heroComobo.plist", texture);
break;
case 8:
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("pnglist/heroGun.plist", texture);
this->schedule(schedule_selector(SplashLayer::nextScene), 1, 1, 1);
break;
default:
break;
}
}

void SplashLayer::loadingAudio()
{
log("loadAudio");
//初始化 音乐
SimpleAudioEngine::getInstance()->preloadBackgroundMusic("Sound/startBGM.mp3");
//初始化音效
SimpleAudioEngine::getInstance()->preloadEffect("Sound/button.wav");
}

void SplashLayer::initUserData()
{
setIntToXML(GAMELEVEL_KEY, 1); // 初始化关卡
setIntToXML(HEROENERGY_KEY, 10); // 初始化体力
setIntToXML(HEROCOIN_KEY, 1000); // 初始化金币
setBoolToXML(SOUND_KEY, true);
setBoolToXML(MUSIC_KEY, true);
// 刷新
UserDefault::getInstance()->flush();
}

void SplashLayer::nextScene(float dt)
{
Director::getInstance()->replaceScene(TransitionFade::create(2.0f, StartLayer::createScene()));
}

void SplashLayer::onExit()
{
Layer::onExit();
_loadingAudioThread->join();
CC_SAFE_DELETE(_loadingAudioThread);
this->unschedule(schedule_selector(SplashLayer::nextScene));
}