【cocos2d-x入门实战】微信飞机大战之十二:分数的本地存储

时间:2023-02-07 18:20:54

原创作品,转载请标明http://blog.csdn.net/jackystudio/article/details/12036237

作为一个单机游戏,连分数存储的的功能都没有,让它怎么在单机游戏圈里混,其它单机游戏又会怎么看它,这么碎节操的事不能干。。。

好吧,不废话。。。这篇就要针对游戏分数来介绍数据的本地存储。至于具体在哪里实现,因为涉及开场场景和结束场景的设计,篇幅有限,就先不写,这里讨论怎么实现。


1.分数的设计

在GameLayer层增加成员变量。

int score;//实时分数

在GameOverLayer层增加成员变量,这层是游戏结束画面,放在GameOverScene中,后面会介绍。

static int highestHistoryScore;//历史最高分

(1)highestHistoryScore是游戏一开始读取出来的历史最高分,这个值除非在刷新记录后才会变化,否则是不变的。

(2)score是当前局游戏的分数,影响到它的有:

A.初始化为0。

B.命中敌机增加相应的分数(3种)。

C.炸弹ufo全局秒杀增加相应分数。


2.分数的显示和更新

如昨天所言,分数显示在ControlLayer这一层中,如下

//在ControlLayer的init加入score
scoreItem=CCLabelBMFont::create("0","font/font.fnt");//scoreItem是CCLabelBMFont*型成员变量,这里采用了自定义的字体,相关资源在第一篇有给出了
scoreItem->setColor(ccc3(143,146,147));
scoreItem->setAnchorPoint(ccp(0,0.5));
scoreItem->setPosition(ccp(pPauseItem->getPositionX()+normalPause->getContentSize().width/2+5,pPauseItem->getPositionY()));
this->addChild(scoreItem);
分数的更新也由ControlLayer提供接口

//更新分数
void ControlLayer::updateScore(int score)
{
	if (score>=0 && score<=MAX_SCORE)//设置一个最大值20亿
	{
		CCString* strScore=CCString::createWithFormat("%d",score);//格式化为字符串
		scoreItem->setString(strScore->m_sString.c_str());//从CCString中获得char*,更新分数
	}
}


3.分数更新的调用

这里举的例子是Enmey3和Bullet碰撞后的检测,以下这段代码可以在第九篇:碰撞检测中找到。

				//如果life==1,移除enemy3
				else if(enemy3->getLife()==1)
				{
					enemy3->loseLife();
					bulletsToDelete->addObject(bullet);
					enemy3sToDelete->addObject(enemy3);
					score+=ENEMY3_SCORE;
					this->controlLayer->updateScore(score);//更新分数
				}

4.分数的本地存储

分数的存储,其实就是在本地保存一个xml的文本,记录相关数据。有点类似ini文件,游戏中只有在以下几个地方用到:

(1)进入游戏,读取历史最高分,如果没有存档(第一次进游戏或者文档被删除),重新写存档,初始分数默认为0。

(2)游戏结束,比较历史最高分和当前分数,如果当前分数超过了历史最高分,设置当前分数为历史最高分,重新写入存档。

这里用到的类是CCUserDefault。

4.1.获取历史最高分

WelcomeLayer属于开场场景

bool WelcomeLayer::isHaveSaveFile()//判断存档是否存在
{
	if(!CCUserDefault::sharedUserDefault()->getBoolForKey("isHaveSaveFileXml"))//通过设置的bool型标志位判断,如果不存在
	{
		CCUserDefault::sharedUserDefault()->setBoolForKey("isHaveSaveFileXml", true);//写入bool判断位
		CCUserDefault::sharedUserDefault()->setIntegerForKey("HighestScore",0);//写入初始分数0
		CCUserDefault::sharedUserDefault()->flush();//设置完一定要调用flush,才能从缓冲写入io
		return false;
	}
	else
	{
		return true;
	}
}

void WelcomeLayer::getHighestHistorySorce()
{
	if (isHaveSaveFile())//如果存在存档
	{
		GameOverLayer::highestHistoryScore=CCUserDefault::sharedUserDefault()->getIntegerForKey("HighestScore",0);//读取历史最高分
	}
}

4.2.设置新的最高分

//GameOver层中调用
if (score>highestHistoryScore)
{
	CCUserDefault::sharedUserDefault()->setIntegerForKey("HighestScore",score);//修改存档
	highestHistoryScore=score//最高分重新设定...后面还有其他东西
}

5.数据的加密存储

在游戏目录下可以找到这么一个文件UserDefault.xml,就可以看到isHaveSaveFileXml和HighestScore这两个值,如果人人都可以修改了它,分数就可以造假了。

【cocos2d-x入门实战】微信飞机大战之十二:分数的本地存储
那怎么办?

加密呗。google一份Base64的C++源码(.h和.cpp),添加到工程中,直接调用API(Encode和Decode)即可实现,这里就不说了。或者你有兴趣自己写加密解密算法,也是不错的选择。

效果图:

【cocos2d-x入门实战】微信飞机大战之十二:分数的本地存储