载入资源是游戏中常见的过程,其目的是要把资源预加载到内存。那么在常见游戏设计中,一般都会在关卡开始有一个加载资源场景,当资源加载完后再跳转到游戏主场景,
那么,这个场景就很有必要进行封装。
1、定义一个继承自CCProgressTimer的类,
class ProgressBar : public cocos2d::CCProgressTimer
{
public:
ProgressBar(void);
virtual ~ProgressBar(void);
/**
* @brief
*
* @param target ProgressDelegate
* @param sprite ProgressBarSprite
*
* @return
*/
static ProgressBar* create(ProgressDelegate* target, cocos2d::CCSprite* sprite);
bool init(ProgressDelegate* target, cocos2d::CCSprite* sprite);
/**
* @brief 增加一个百分比
*
* @param delta 增加值
*/
void progressBy(float delta);
/**
* @brief 增加到一个百分比
*
* @param destination 目标值
*/
void progressTo(float destination);
/**
* @brief 设置进度条前进的速率
*
* @param Speed 速率
*
* @return
*/
CC_SYNTHESIZE(float, _speed, Speed);
CC_SYNTHESIZE(ProgressDelegate*, _target, Target);
/**
* @brief 为进度条添加前景或背景
*
* @param Foreground 前景,例如进度条的当前的百分比值
* @param Background 背景
*
* @return
*/
CC_PROPERTY(cocos2d::CCNode*, _background, Background);
CC_PROPERTY(cocos2d::CCNode*, _foreground, Foreground);
protected:
//更新百分比
void updatePercentage();
//载入完成
void loadingFinished();
};
2、定义一个代理类,实现加载完成后目标类的实现(C++中没有接口,所以可以定义纯虚类来实现一个协议)
class ProgressDelegate
{
public:
virtual void loadingFinished() = 0;
virtual void progressPercentageSetter(float percentage){return;};
};
3、实现进度条
#define PROGRESS_ACTION 1
ProgressBar::ProgressBar(void) {
}
ProgressBar::~ProgressBar(void) {
}
ProgressBar* ProgressBar::create(ProgressDelegate* target, CCSprite* sprite) {
ProgressBar* progressBar = new ProgressBar();
progressBar->init(target, sprite);
progressBar->autorelease();
return progressBar;
}
bool ProgressBar::init(ProgressDelegate* target, CCSprite* sprite) {
CCProgressTimer::initWithSprite(sprite);
this->setTarget(target);
this->setSpeed(1.0f);
//设置计时运动方向 ccp在0到1之间
this->setMidpoint(CCPointMake(0, 0));
//设置计时器的宽高起始比例,1表示开始,0表示充满
this->setBarChangeRate(CCPointMake(1, 0));
//设置当前的进度动画目标渲染类型,这里使用条形的进度动画
/*
两种不同的进度动画目标渲染类型。
typedef enum {
///绕圆心转动的进度动画
kCCProgressTimerTypeRadial,
///条形的进度动画。
kCCProgressTimerTypeBar,
} CCProgressTimerType;
*/
this->setType(kCCProgressTimerTypeBar);
return true;
}
void ProgressBar::progressBy(float delta) {
float maxPercentage = 100.0f;//最大百分比为100
bool isFinished = false;
float nextPercentage = delta + this->getPercentage();
if(nextPercentage >= maxPercentage) {//判断是否百分百
nextPercentage = maxPercentage;
isFinished = true;
}
//结束上一个动作
this->stopActionByTag(PROGRESS_ACTION);
CCArray* actions = CCArray::createWithCapacity(2);
float duration = delta / this->getSpeed();//计算进度时长
//参一为动画时长,参二为结束进度值
CCProgressTo* to = CCProgressTo::create(duration, nextPercentage);
actions->addObject(to);
if(isFinished){//载入完成后执行loadingFinished
CCCallFunc* callfunc = CCCallFunc::create(this, callfunc_selector(ProgressBar::loadingFinished));
actions->addObject(callfunc);
}
CCFiniteTimeAction* seq = CCSequence::create(actions);
//更新百分比显示
CCCallFunc* updatePercentage = CCCallFunc::create(this, callfunc_selector(ProgressBar::updatePercentage));
updatePercentage->setDuration(duration);
CCSpawn* spawn = CCSpawn::createWithTwoActions(seq, updatePercentage);
spawn->setTag(PROGRESS_ACTION);
this->runAction(spawn);
}
void ProgressBar::progressTo(float destination) {
//默认this->getPercentage()为0.0
float delta = destination - this->getPercentage();
this->progressBy(delta);
}
void ProgressBar::updatePercentage() {
_target->progressPercentageSetter(this->getPercentage());//更新百分比
}
void ProgressBar::loadingFinished() {
_target->loadingFinished();//执行目标功能
}
//设置前景和背景 start
void ProgressBar::setBackground(CCNode* bg) {
this->removeChild(_background, true);
_background = bg;
CCSize size = this->getSprite()->getContentSize();
_background->setPosition(CCPointMake(size.width * 0.5, size.height * 0.5));
this->addChild(_background, -1);
}
CCNode* ProgressBar::getBackground() {
return _background;
}
void ProgressBar::setForeground(CCNode* fg) {
this->removeChild(_foreground, true);
_foreground = fg;
CCSize size = this->getSprite()->getContentSize();
_foreground->setPosition(CCPointMake(size.width * 0.5, size.height * 0.5));
this->addChild(_foreground, 1);
}
CCNode* ProgressBar::getForeground() {
return _foreground;
}
//设置前景和背景 end
4、在读取场景中使用ProgressBar
首先要继承和实现ProgressDelegate类中两个函数
class LoadingLayer : public CCLayer, public ProgressDelegate {
public:
virtual ~LoadingLayer();
bool init();
CREATE_FUNC(LoadingLayer);
void loadingFinished();//加载完成
void progressPercentageSetter(float percentage);
void curMission(CCObject* pSender);
void onStartGame(CCObject* pSender);//跳转游戏主页面
protected:
ProgressBar* _progressBar;//进度条
CCLabelTTF* _progressFg;//进度条百分比文字
void loading(CCObject* pSender);//异步加载纹理时调用计算百分比
void cacheInit();//加载plist缓存
void cacheAnim();//加载动画缓存
void audioAndUserDataInit();//初始化容器和用户数据及音乐
void initializationCompleted();//加载完成
unsigned int _cur_mission;//当前关卡
};
在cocos2d-x引擎中,提供了一个异步加载图片的方法addImageAsync
初始化ProgressBar
//把图片加载进入内存,然后调用londing
//加载进度条图片
CCSprite* progressBg = CCSprite::createWithSpriteFrameName(loading_progress_bar_png);
//加载进度条显示百分比的文字
//_progressFg = CCLabelTTF::create("0/100", "Thonburi", 16);
//_progressFg->setColor(ccc3(0, 0, 0));
//加载进度条
_progressBar = ProgressBar::create(this, CCSprite::createWithSpriteFrameName(loading_progress_bar_back_png));
_progressBar->setBackground(progressBg);
//_progressBar->setForeground(_progressFg);
_progressBar->setAnchorPoint(CCPointZero);
_progressBar->setPosition(CCPointMake(ScreenWidth * 0.017, ScreenHeight * 0.19));
_progressBar->setSpeed(100.0);
this->addChild(_progressBar);
然后异步加载图片到内存中
CCTextureCache::sharedTextureCache()->addImageAsync(player_ships_png, this, callfuncO_selector(LoadingLayer::loading));
在其中的loading方法中调用ProgressBar的刷新进度方法
void LoadingLayer::loading(CCObject* pSender) {
_progressBar->progressTo(100.0);
}
当完成了加载到了100%后ProgressBar会自动调用继承了ProgressDelegate并实现了的loadingFinished方法,可以再这个方法中实现你所想要的逻辑
void LoadingLayer::loadingFinished() {
EnemyManage::shareEnemyManage();//初始化敌机的管理
this->cacheInit();//将资源缓存到内存
this->cacheAnim();//缓存动画
this->initializationCompleted();//初始化开始菜单
}