• Cocos2d-x3.0游戏实例《不要救我》第十篇(结束)——使用Json配置数据类型的怪物



    如今我们有2种类型的怪物,并且创建的时候是写死在代码里的,这是要作死的节奏~

    所以。必须可配置。不然会累死人的。

     

    笨木头花心贡献,啥?花心?不呢,是用心~

    转载请注明,原文地址: http://www.benmutou.com/blog/archives/949 

    文章来源:笨木头与游戏开发

     

    Json文件

    什么是Json文件?说白了。它就是一个文本文档。仅仅只是它的内容是依照一定的规则填写的。

    于是,我们就能够依照那个规则去读取这份文档。

    这,就是配置文件产生的缘由(才怪)。

    (小若:才怪是什么意思啊喂!)

     

    我不知道配置文件产生的历史,但它的原理就是这种~

     

    关于Json的资料。百度非常多,我坦白。我自己也没有深入地完整地使用过Json的全部东西。

    所以,大家感兴趣的,能够百度一下。

     

    怪物类型配置文件

    我们在这个游戏要用到的Json格式主要是数组(array)和对象(object),来我们在项目的Resources文件夹下创建一个新文件,命名为:monsterConf.plist

     

    然后随便用一个文本编辑器打开,输入下面内容:

    [

    {"id":1, "atk":1, "model":"item2.png"} // 1.普通。-1HP

    ,{"id":2, "atk":-1, "model":"heart_red.png"}// 2.爱心,+1HP

    ]

    非常明显。由符号“[]”框起来的就是数组,数组里面用“{}”包围起来的,就是对象,对象之间有逗号分隔。

     

    里面就是我们的怪物配置,这里我们仅仅填写id、atk、model三个属性,完整版的《别救我》里面是有9个属性的。

     

    导入Json库

    要想在程序中读写Json文件,我们就用别人已经写好的库,说库太高深了,就是一些h和cpp文件。

    我使用的是JsonCpp库,大家能够到这里下载:http://download.csdn.net/detail/musicvs/7392931

     

    下载好后,解压json文件夹到项目的Classes文件夹下,然后就像导入代码文件一样导入到项目中就能够了。

    如图:

    Cocos2d-x3.0游戏实例之《别救我》第十篇——用Json配置各类型怪物数据

    Cocos2d-x3.0游戏实例之《别救我》第十篇——用Json配置各类型怪物数据

    Cocos2d-x3.0游戏实例之《别救我》第十篇——用Json配置各类型怪物数据

    Cocos2d-x3.0游戏实例之《别救我》第十篇——用Json配置各类型怪物数据

    在程序中读取Json配置文件

    好。这次真的是最后一步了,我们改动Monster的init函数:

    1. bool Monster::init(int ID)
    2. {
    3.     this->m_ID = ID;
    4.  
    5.     /* ----------- 读取怪物配置文件 ------------ */
    6.  
    7.     /* 读取配置文件字符串数据 */
    8.     std::string sData = FileUtils::getInstance()->getStringFromFile("monsterConf.plist");
    9.  
    10.     /* 用于解析Json */
    11.     Json::Reader reader;
    12.     
    13.     /* 解析Json后的根节点 */
    14.     Json::Value root;
    15.  
    16.     /* 開始解析 */
    17.     if (!reader.parse(sData, root, false))
    18.     {
    19.         return false;
    20.     }
    21.  
    22.     /* 在这里。根节点是一个数组,遍历数组,找到我们要的ID */
    23.     int size = root.size();
    24.     for (int i = 0; i < size; ++i)
    25.     {
    26.         int id = root[i]["id"].asInt();
    27.  
    28.         if (id == ID)
    29.         {
    30.             m_sModelPath = root[i]["model"].asCString();
    31.             break;
    32.         }
    33.     }
    34.  
    35.     return true;
    36. }

    有点小复杂,没关系。你们自己理解理解就好了…啊才怪啊,怎么可能!

    (小若:抢我台词O_O)

     

    解释例如以下:

    1. 首先,用FileUtils的getStringFromFile函数能够把文件读取成字符串格式,Json解析须要用到

    2. 然后用Json库的Reader类能够解析Json文件

    3. 解析之后。根节点赋值给root,通过root能够找到其它子节点

    4. 由于我们配置文件中根节点就是一个数组,我们是用数组包围了怪物的配置数据的,没忘记吧?看看配置文件就知道了。整个数据是用“[]”符号包围的~

    5. 然后遍历root节点。就像数组一样遍历

    6. 比方root[0],那就是第一条怪物配置数据,然后通过root[0][“id”]就能找到这条数据的id字段的值

    7. 找到我们ID配置的数据。然后获取它的全部字段,眼下我们要用到的仅仅有model字段而已。

     

    OK,别忘了,要使用Json库的类,把头文件也在Monster顶部加上:

    1. #include "jsonwriter.h"
    2. #include "json eader.h"

     

    然后,编译执行,效果和之前是一样的,证明我们已经成功。

     

    PS:有人反馈Json库编译报一堆错误,试试下面操作:

    项目属性,【C/C++】->【常规】->【附加包括文件夹】,看看”..Classes”这一条有没有加上去,并且是不是在第一条。把它放在第一条试试。


    额外的说明

    或许大家要喷了。各种疑问:

    1. 为什么读取一个配置文件就这么复杂,这么多部分。那不是非常麻烦?

    答:由于这是实例教程,不想涉及太多的东西,所以我就尽量没有去封装了,在完整版里我是封装了一个JsonData类的,解析Json文件仅仅需简单的一、两句话。

    2. 每创建一个怪物对象,就要这样解析一次。岂不是非常浪费效率?

    答:效率浪不浪费我就没有去试验了,可是实际开发中肯定不会这样做的。

    在完整版的《别救我》里,我是预先载入好怪物的配置文件。然后作为一个个对象(MonsterConfig)缓存起来,要使用的时候。直接依据怪物ID获取就能够了。

    不会每次都去解析Json。

     

    总之。一切从简。点到即止。否则我这教程不知道得写到什么时候了。

     

    最后,主角和怪物的碰撞

    最后完好一个功能点,主角和怪物的碰撞,非常easy,不须要加东西。

     

    OK,执行游戏。然后我已经把怪物全都撞没了~如图:

    Cocos2d-x3.0游戏实例之《别救我》第十篇——用Json配置各类型怪物数据

    Cocos2d-x3.0游戏实例之《别救我》第十篇——用Json配置各类型怪物数据

    (小若:等等。刚刚发生了什么事情?)

     

    刚刚大家被我弄昏了(邪恶),我们回到刚刚的时间…

     

    最后完好一个功能点,主角和怪物的碰撞。非常easy,不须要加东西。

     

    改动一下TollgateScene的onContactBegin函数:

    1. bool TollgateScene::onContactBegin(PhysicsContact& contact)
    2. {
    3.     /* 这里省略了非常多代码 */
    4.  
    5.     /* 碰撞到边缘锯齿(墙),+1血 */
    6.     if (other->getTag() == ObjectTag_Border)
    7.     {
    8.         /* 扣-1血。就相当于加1血 */
    9.         player->beAtked(-1);
    10.  
    11.         log("player cur HP:%d", player->getiHP());
    12.     }
    13.     else if (other->getTag() == ObjectTag_Monster)
    14.     {
    15.         /* 碰撞到怪物。依据怪物的属性进行操作 */
    16.         Monster* monster = (Monster*)other;
    17.  
    18.         if (monster->getiAtk() != 0)
    19.         {
    20.             /* 攻击玩家(可能是加血) */
    21.             player->beAtked(monster->getiAtk());
    22.  
    23.             /* 碰撞之后,怪物消失 */
    24.             monster->removeFromParent();
    25.         }
    26.     }
    27.     return true;
    28. }

    我们新增了一个else if分支,推断假设other是怪物的话。那就对玩家进行攻击(或者加血)。碰撞怪物之后,怪物就消失。

     

    OK,如今执行游戏,我们就能够用主角碰撞怪物。然后怪物消失。

    同一时候主角的HP会不断变化(从日志中查看)。

     

    在《别救我》完整版里,玩家的任务是让主角的血量为0,所以是不能碰撞那些会加血的怪物的。

    并且怪物也不是碰一下就消失。有些要碰好几下。

    总之,所以的这一切都能通过改动怪物的配置文件来实现,给怪物加属性配置字段。我们就能实现多种多样的功能。

     

    同一时候,还能通过改动TiledMap关卡配置文件。给矩形对象加入很多其它属性,比方加入怪物出场时的推力属性,这样怪物出场的时候就会往某个方向喷射。(于是连飞机大战都能做出来。所以这个就靠想象力了)

    我给大家看一个完整版的关卡配置:

    Cocos2d-x3.0游戏实例之《别救我》第十篇——用Json配置各类型怪物数据

    Cocos2d-x3.0游戏实例之《别救我》第十篇——用Json配置各类型怪物数据

    蓝色的怪物在出场的时候是会往上飞的,看起来就像是飞机的子弹,非常有意思的配置吧~

     

    OK,《别救我》全部的核心功能已经完毕。剩下的,就是各种开场动画、菜单、UI、关卡了。

    记得把物理引擎的调试模式关掉,不然会一直有非常多红色的线。

     

    结束语

    好了,《别救我》简化版游戏实例教程,到此结束。

    希望多多少少能帮到大家。

     

    假设对完整版感兴趣的,能够到我的淘宝店购买完整版源代码。这是对我最好的物质支持~地址:果断要看看

     

    假设对完整版不感兴趣的,又想支持我的(哎呀,大家太热情了我也不想的(害羞)),能够点击我博客右上方的的“支付宝捐赠”。任意一下~

    尽管捐赠不能让我成为土豪。可是它是对我最好的精神支持~

     

     

     

    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    JavaScript 实现打印操作
    linux-centos7.6设置固定IP网络方法
    VMware网络配置三种网络模式(桥接、NAT、Host-only)
    SVN 执行cleanup报错:Cleanup failed to process the following paths
    word生成目录的pdf
    win10开机后将存在多个系统选择,改为直接进入系统无需选择
    Win10删除或是不显示快速访问中最近使用文件记录
    Dell T30解决报Alert! Cover was previously removed.
    WIN10安装.net报0x800F081F解决方法
    查看SVN当前登录用户
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4841118.html
Copyright © 2020-2023  润新知