离线下载
PDF版 ePub版

偶尔e网事 · 更新于 2018-11-28 11:00:43

分数的本地存储

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

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

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碰撞后的检测,以下这段代码可以在[第九篇:碰撞检测][1]中找到。

//如果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这两个值,如果人人都可以修改了它,分数就可以造假了。

那怎么办?

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

效果图: