首页 > 代码库 > 【cocos2d-x 3.7 飞机大战】 决战南海I (七) 控制器的实现

【cocos2d-x 3.7 飞机大战】 决战南海I (七) 控制器的实现

        控制器中的功能并不多,主要是以下这些

//对玩家分数的操作
	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");
	}


仅仅有背景音乐处于播放状态,音效才会播放。

尽管功能实现了,只是总感觉方法太水了。。。谁有更好的方式欢迎告知。



【cocos2d-x 3.7 飞机大战】 决战南海I (七) 控制器的实现