控制器中的功能并不多,主要是下面這些
~~~
//對玩家分數的操作
CC_SYNTHESIZE_READONLY(SaveData *, m_saveData, SaveData);
void update(float tm);
//游戲暫停與恢復
void menuPauseCallback(cocos2d::Ref* pSender);
//聲音控制
void menuMusicCallback(cocos2d::Ref* pSender);
~~~
下面是這些功能的實現
~~~
bool Controller::init()
{
if (!Layer::init())
{
return false;
}
bool bRect = false;
do
{
Size winSize = Director::getInstance()->getWinSize();
//從xml文件中讀取中文顯示出來
auto dictionary = Dictionary::createWithContentsOfFile("fonts/AboutMe.xml");
score_label = Label::createWithTTF(
((__String *)(dictionary->objectForKey("score")))->getCString(),
"fonts/DFPShaoNvW5-GB.ttf",
25);
score_label->setPosition(score_label->getContentSize().width / 2,
winSize.height - score_label->getContentSize().height * 2);
CC_BREAK_IF(!score_label);
this->addChild(score_label);
//添加顯示分數的標簽
m_saveData = SaveData::create();
//這里一定要retain一下saveData,在析構函數中release一下
m_saveData->retain();
auto str = __String::createWithFormat("%d", m_saveData->getScore());
m_score = Label::createWithTTF(str->getCString(), "fonts/DFPShaoNvW5-GB.ttf", 25);
m_score->setPosition(Point(score_label->getContentSize().width + m_score->getContentSize().width / 2 + 30,
winSize.height - score_label->getContentSize().height * 2));
CC_BREAK_IF(!m_score);
this->addChild(m_score);
//記得更新分數的顯示
this->scheduleUpdate();
//游戲聲音控制按鈕
Sprite *normalMusic = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("game_musicPause.png"));
Sprite *pressedMusic = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("game_musicPause.png"));
pMusicItem = MenuItemSprite::create(
normalMusic,
normalMusic,
NULL,
CC_CALLBACK_1(Controller::menuMusicCallback, this));
//游戲暫停按鈕
Sprite *normalPause = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("game_resume_nor.png"));
Sprite *pressedPause = Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("game_resume_pressed.png"));
pPauseItem = MenuItemSprite::create(
normalPause,
pressedPause,
NULL,
CC_CALLBACK_1(Controller::menuPauseCallback, this));
Menu *menuPause = Menu::create(pMusicItem,pPauseItem, NULL);
menuPause->alignItemsHorizontallyWithPadding(pPauseItem->getContentSize().width/2);
menuPause->setPosition(
Point(winSize.width - pPauseItem->getContentSize().width*2, winSize.height - normalPause->getContentSize().height));
this->addChild(menuPause);
} while (0);
return true;
}
//游戲暫停
void Controller::menuPauseCallback(cocos2d::Ref* pSender)
{
CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("sound/button.mp3");
if (!Director::getInstance()->isPaused())
{
// 圖標狀態設置
pPauseItem->setNormalImage(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("game_pause_nor.png")));
pPauseItem->setSelectedImage(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("game_pause_press.png")));
CocosDenshion::SimpleAudioEngine::getInstance()->pauseBackgroundMusic(); // 停止背景音樂
CocosDenshion::SimpleAudioEngine::getInstance()->stopAllEffects(); // 停止所有的特效
Director::getInstance()->pause(); // 停止所有的動作,敵機飛行,子彈前進等
}
else
{
pPauseItem->setNormalImage(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("game_resume_nor.png")));
pPauseItem->setSelectedImage(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("game_resume_pressed.png")));
CocosDenshion::SimpleAudioEngine::getInstance()->resumeBackgroundMusic();// 恢復
Director::getInstance()->resume(); // 恢復
}
}
void Controller::menuMusicCallback(cocos2d::Ref* pSender)
{
CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("sound/button.mp3");
if (CocosDenshion::SimpleAudioEngine::getInstance()->isBackgroundMusicPlaying())
{
// 圖標狀態設置
pMusicItem->setNormalImage(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("game_music.png")));
pMusicItem->setSelectedImage(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("game_music.png")));
CocosDenshion::SimpleAudioEngine::getInstance()->stopBackgroundMusic(); // 停止背景音樂
// CocosDenshion::SimpleAudioEngine::getInstance()->stopAllEffects(); // 停止所有的特效
}
else
{
pMusicItem->setNormalImage(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("game_musicPause.png")));
pMusicItem->setSelectedImage(Sprite::createWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("game_musicPause.png")));
CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic("sound/BackgroundMusic.mp3", true);// 恢復
// CocosDenshion::SimpleAudioEngine::getInstance()->resumeAllEffects();
}
}
void Controller::update(float tm)
{
auto str = __String::createWithFormat("%d", m_saveData->getScore());
//更新分數和坐標
m_score->setColor(Color3B(255, 0, 0));
m_score->setString(str->getCString());
m_score->setPositionX(score_label->getContentSize().width + m_score->getContentSize().width / 2 + 30);
}
~~~
要實現游戲的暫停功能,可以直接將當前運行的場景暫停,而要實現聲音的暫停,通過簡單的停止背景音樂、音效卻不行。因為不斷有新的子彈在發射、新的敵機在爆炸等。所以,我使用的方法是 將背景音樂與其他音效綁定。
比如下面子彈類中的代碼
~~~
if (CocosDenshion::SimpleAudioEngine::getInstance()->isBackgroundMusicPlaying())
{
CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("sound/bullet.wav");
}
~~~
只有背景音樂處于播放狀態,音效才會播放。
雖然功能實現了,不過總感覺方法太水了。。。誰有更好的方式歡迎告知。