(七) 控制器的实现
最后更新于:2022-04-01 16:12:20
控制器中的功能并不多,主要是下面这些
~~~
//对玩家分数的操作
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");
}
~~~
只有背景音乐处于播放状态,音效才会播放。
虽然功能实现了,不过总感觉方法太水了。。。谁有更好的方式欢迎告知。