转载请表明地址: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碰撞后的检测,以下这段代码可以在第九篇:碰撞检测中找到http://blog.csdn.net/jackystudio/article/details/11917875
//如果life==1,移除enemy3, else if(enemy3->life==1) { enemy3->life--; mutiBulletsToDelete->addObject(mutiBullets); enemy3sToDelete->addObject(enemy3); score+=ENEMY3_SCORE;//增加分数,ENMEY3_SCORE是一个宏,值是击落敌机3获得的分数 this->controlLayer->updateScore(score);//调用ControlLayer的updateScore更新分数 }
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);//修改存档 //...其他东西 }
5.数据的加密存储
在游戏目录下可以找到这么一个文件UserDefault.xml,就可以看到isHaveSaveFileXml和HighestScore这两个值,如果人人都可以修改了它,分数就可以造假了。
那怎么办?
加密呗。google一份Base64的C++源码(.h和.cpp),添加到工程中,直接调用API(Encode和Decode)即可实现,这里就不说了。或者你有兴趣自己写加密解密算法,也是不错的选择。
效果图: