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


    转载请表明地址: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)即可实现,这里就不说了。或者你有兴趣自己写加密解密算法,也是不错的选择。

    效果图:


  • 相关阅读:
    继承(JAVA)
    第一个Java应用
    Java面向对象编程
    学生管理系统(分层开发)
    ComboBox的数据联动
    二进制、八进制、十进制、十六进制之间的转换
    C# using的一些事
    JVM最多支持多少个线程?
    Java日志体系居然这么复杂?——架构篇
    java 架构之路(队列)kafka
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3341563.html
Copyright © 2020-2023  润新知