如果玩家不死的话,对于玩家来说就没有什么挑战性了,所以我们必须得让玩家“死”。条件就是玩家飞机和敌机碰撞的时候或者碰撞到了炸弹道具的时候,然后切换到游戏结束场景,所以,我们必须实现一个游戏结束场景。在游戏结束场景中,添加背景图片,添加玩家的最后得分,添加返回游戏开始场景的按钮,就是这些,看看代码吧。

#ifndef _GAME_OVER_H_
#define _GAME_OVER_H_
#include "cocos2d.h"
//开始游戏场景
#include "StartGame.h"

USING_NS_CC;

//游戏结束场景
class GameOver : public Layer
{
public:
	GameOver(void);
	~GameOver(void);
public:
	static Scene * createScene();
	bool init();
	CREATE_FUNC(GameOver);
public:
	//回到游戏的回调函数
	void backGame(Ref * ref);
};

#endif
#include "GameOver.h"

GameOver::GameOver(void)
{
}

GameOver::~GameOver(void)
{
}

Scene * GameOver::createScene()
{
	auto scene = Scene::create();
	auto layer = GameOver::create();
	scene->addChild(layer);

	return scene;
}

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

	auto size = Director::getInstance()->getWinSize();

	//设置背景图片
	auto background = Sprite::createWithSpriteFrameName("gameover.png");
	background->setPosition(Point(size.width/2,size.height/2));
	this->addChild(background);

	//添加回到游戏的菜单
	auto returnItem = MenuItemImage::create();
	returnItem->setNormalSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName("btn_finish.png"));
	returnItem->setCallback(CC_CALLBACK_1(GameOver::backGame,this));
	auto menu = Menu::create(returnItem,NULL);
	menu->setPosition(Point(size.width/2,size.height*0.3));
	this->addChild(menu);

	//添加玩家得分
	auto score_int = UserDefault::getInstance()->getIntegerForKey("currentScore");
	auto score_str = __String::createWithFormat("%d",score_int);
	auto score = Label::createWithTTF(score_str->getCString(),"font/arial.ttf",40);
	score->setPosition(Point(size.width/2,size.height/2));
	score->setColor(Color3B(100,100,100));
	this->addChild(score);

	return true;
}

void GameOver::backGame(Ref * ref)
{
	//切换到开始游戏的场景
	Director::getInstance()->replaceScene(StartGame::createScene());
}

玩家得分的获取是通过currentScore这个键得到的,在save数据的时候我们需要sava一下这个键值对,同时sava函数还有一些bug,为了消除这些bug,我将sava函数修改如下。

void SaveData::save()
{
	/*本函数的整体思路是先对vector中保存的玩家数据进行排序,然后重新写入到xml文件中*/

	//将玩家的分数保存到set集合中,以便排序,分数和原先的分数不同才保存
	int i=0;
	for(auto tem:m_vector)
	{
		if(tem.asInt() == m_score)
		{
			break;
		}
		i++;
	}
	if(i == m_vector.size())
	{
		m_vector.push_back(Value(m_score));
		//自定义排序函数,对m_vector中的内容进行排序,方便以后对数据的操作
		auto sortData = [](Value value1,Value value2)
		{
			return value1.asInt()>value2.asInt();
		};
		//调用c++模板中的sort函数进行排序,前俩个参数是数组的地址,最后一个参数是使用的排序函数
		std::sort(m_vector.begin(),m_vector.end(),sortData);

		//将玩家的得分保存在文件中
		for(int i=0;i<m_vector.size();i++)
		{
			auto value = m_vector.at(i);
			auto index = __String::createWithFormat("%d",i);
			m_userDefault->setIntegerForKey(index->getCString(),value.asInt());
		}
	}

	//单独保存本次游戏的得分
	UserDefault::getInstance()->setIntegerForKey("currentScore",m_score);
	//重新设置一下count
	UserDefault::getInstance()->setIntegerForKey("count",m_vector.size());

	//刷新
	m_userDefault->flush();
}

接着就是对玩家死亡条件的判断了,开始的时候说的很清楚了,下面把实现贴在这里。

/*玩家飞机和敌机的碰撞检测*/
	for(auto enemy : enemyVector)
	{
		//如果敌机毁灭会播放动画暂时还不会从管理器中移除,所以这里要判断一下是否已经毁灭
		if(enemy->getHp() == 0)
		{
			//如果已经毁灭就不要进行碰撞检测了
			continue;
		}

		auto rect = this->m_player->getBoundingBox();
		auto point = enemy->getPosition();
		if(rect.containsPoint(point))
		{
			this->gameOver();
		}
	}
//游戏结束
void MainGame::gameOver()
{
	//保存游戏数据
	this->m_ui->getSaveData()->save();

	//停止发射子弹
	this->unschedule(SEL_SCHEDULE(&MainGame::addBullet));
	this->unschedule(SEL_SCHEDULE(&MainGame::addBulletByUfo));

	//玩家飞机炸毁的动画
	Vector<SpriteFrame *> vector;
	for(int i=0;i<4;i++)
	{
		auto frameName = __String::createWithFormat("hero_blowup_n%d.png",i+1);
		auto frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(frameName->getCString());
		vector.pushBack(frame);
	}
	auto animation = Animation::createWithSpriteFrames(vector,0.3f,1);
	auto animate = Animate::create(animation);
	//切换场景
	auto func = []()
	{
		//碰到炸弹的处理和碰到敌机的处理是相同的
		Director::getInstance()->replaceScene(GameOver::createScene());
	};
	//执行动作序列
	auto sequence = Sequence::create(animate,CallFunc::create(func),NULL);
	this->m_player->runAction(sequence);
}

玩家飞机和敌机的碰撞检测写在isHitEnemy碰撞检测函数中,同时在飞机和炸弹道具碰撞的时候也要调用gameOver函数。

3.0实现飞机大战——游戏结束场景