• 《入门级-Cocos2dx4.0 塔防游戏开发》---第十一课:游戏地图信息初始化


    目录

    一、开发环境

    二、开发内容

    2.1 plist文件结构讲解

    2.1.1 plist中string标签和array标签的读取

    2.1.2 plist中dict、integer、date标签的读取

    2.2 怪物信息plist结构体说明

    2.3 怪物信息加载

    2.4 路线信息plist结构体说明

    2.5 路线信息加载

    三、知识点总结

    3.1 写plist文件

    四、文章导航


    一、开发环境

    操作系统:UOS1060专业版本。

    cocos2dx:版本4.0

    环境搭建教程:统信UOS下配置安装cocos2dx开发环境

    本课主要内容:

    • 怪物信息读取以及路线读取
    • plist的结构讲解。

    文章地址:https://arv000.blog.csdn.net/article/details/132988490

    二、开发内容

            地图的构架如下图,所有游戏地图的处理都是一样的,因此可以将其抽象成父类,每一个关卡根据自己的特点进行重载。

    2.1 plist文件结构讲解

            Plist文件的结构使用类似xml文件的方式进行编写但是与xml文件又有一些差异。他所使用的标签时固定的有一些几种:string、integer、date、data、true、array、dict。

    标签类型说明
    字符串 UTF-8编码的字符串
    整数十进制数字符串
    日期ISO8601格式的日期字符串
    Base64编码的数据
    真或假标签内没内容
     数组可以包含任意数量的子元素
    map标签关键词,值可以时任何标签

    文件开头前三段几乎是固定的,内容如下:

    1. "1.0" encoding="UTF-8"?>
    2. plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    3. <plist version="1.0">

     读取文件内容函数有一下几个getValueMapFromFile、getValueVectorFromFile

    getValueMapFromFile:读取map类型的文件数据对应的

    getValueVectorFromFile:读取map类型的文件数据对应的

    2.1.1 plist中string标签和array标签的读取

            string标签表示的具体的值的标签,通常为了读取他,我们会在外层套上array标签,表示string数据。plist内容如下:      

    1. "1.0" encoding="UTF-8"?>
    2. plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    3. <plist version="1.0">
    4. <array>
    5. <string>苹果string>
    6. <string>香蕉string>
    7. <string>雪梨string>
    8. <string>西瓜string>
    9. array>
    10. plist>

    C++读取文件内容代码如下: 

    1. void HelloWorld::loadPlists1()
    2. {
    3. auto fileUtils = FileUtils::getInstance();
    4. std::string file_path = fileUtils->fullPathForFilename("demo1.plist");
    5. if(fileUtils->isFileExist(file_path)){
    6. ValueVector vectorData = fileUtils->getValueVectorFromFile(file_path);
    7. for(Value item:vectorData){
    8. CCLOG("item:%s;\n",item.asString().c_str());
    9. }
    10. }else{
    11. CCLOG("文件不存在");
    12. }
    13. }

    2.1.2 plist中dict、integer、date标签的读取

            :为map标签他是key和其他数据类型标签配合使用例如,demo2.plist:

    1. "1.0" encoding="UTF-8"?>
    2. plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    3. <plist version="1.0">
    4. <dict>
    5. <key>namekey>
    6. <string>小王string>
    7. <key>agekey>
    8. <integer>18integer>
    9. <key>sexkey>
    10. <true/>
    11. <key>CET4key>
    12. <false />
    13. <key>coursekey>
    14. <array>
    15. <string>语文string>
    16. <string>数学string>
    17. <string>计算机string>
    18. array>
    19. dict>
    20. plist>

    C++的读取代码如下,需要先读取dict为map类型然后根据关键词去获取他的值。

    1. void HelloWorld::loadPlists2()
    2. {
    3. auto fileUtils = FileUtils::getInstance();
    4. std::string file_path = fileUtils->fullPathForFilename("demo2.plist");
    5. if(fileUtils->isFileExist(file_path)){
    6. ValueMap vectorData = fileUtils->getValueMapFromFile(file_path);
    7. std::string name = vectorData.at("name").asString();
    8. int age = vectorData.at("age").asInt();
    9. bool sex = vectorData.at("sex").asBool();
    10. bool CET4 = vectorData.at("CET4").asBool();
    11. ValueVector course = vectorData.at("course").asValueVector();
    12. CCLOG("name:%s,age:%d,sex:%d,CET4:%d",name.c_str(),age,sex,CET4);
    13. for(auto item:course){
    14. CCLOG("item:%s",item.asString().c_str());
    15. }
    16. }else{
    17. }
    18. }

            测试代码地址:https://download.csdn.net/download/arv002/88359605

    2.2 怪物信息plist结构体说明

            在游戏中怪物的派出,是按照波来计算的。每一波中又分好几次派出怪物。每次怪物又有很多的怪物,因此在monster中需要三个array嵌套才能表示。

    1. "1.0" encoding="UTF-8"?>
    2. plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    3. <plist version="1.0">
    4. <dict>
    5. <key>datakey>
    6. <array>
    7. <dict>
    8. <key>goldkey>
    9. <string>500string>
    10. <key>lifekey>
    11. <string>20string>
    12. <key>wavekey>
    13. <string>3string>
    14. dict>
    15. array>
    16. <key>monsterskey>
    17. <array>----- 3波---
    18. <array> --- 每一波 N 次出怪
    19. <array> ---- 每次出怪怪物信息列表----
    20. <dict>
    21. <key>pathkey>
    22. <string>0string>
    23. <key>roadkey>
    24. <string>0string>
    25. <key>typekey>
    26. <string>0string>
    27. dict>
    28. <dict>
    29. <key>pathkey>
    30. <string>2string>
    31. <key>roadkey>
    32. <string>1string>
    33. <key>typekey>
    34. <string>0string>
    35. dict>
    36. <dict>
    37. <key>pathkey>
    38. <string>0string>
    39. <key>roadkey>
    40. <string>2string>
    41. <key>typekey>
    42. <string>-1string>
    43. dict>
    44. <dict>
    45. <key>pathkey>
    46. <string>1string>
    47. <key>roadkey>
    48. <string>3string>
    49. <key>typekey>
    50. <string>-1string>
    51. dict>
    52. array>
    53. <array>
    54. <dict>
    55. <key>pathkey>
    56. <string>0string>
    57. <key>roadkey>
    58. <string>0string>
    59. <key>typekey>
    60. <string>0string>
    61. dict>
    62. array>
    63. <array>
    64. <dict>
    65. <key>pathkey>
    66. <string>0string>
    67. <key>roadkey>
    68. <string>1string>
    69. <key>typekey>
    70. <string>0string>
    71. dict>
    72. array>
    73. <array>
    74. <dict>
    75. <key>pathkey>
    76. <string>1string>
    77. <key>roadkey>
    78. <string>0string>
    79. <key>typekey>
    80. <string>0string>
    81. dict>
    82. array>
    83. <array>
    84. <dict>
    85. <key>pathkey>
    86. <string>2string>
    87. <key>roadkey>
    88. <string>1string>
    89. <key>typekey>
    90. <string>0string>
    91. dict>
    92. array>
    93. array>
    94. <array>
    95. <array>
    96. <dict>
    97. <key>pathkey>
    98. <string>0string>
    99. <key>roadkey>
    100. <string>0string>
    101. <key>typekey>
    102. <string>0string>
    103. dict>
    104. <dict>
    105. <key>pathkey>
    106. <string>2string>
    107. <key>roadkey>
    108. <string>1string>
    109. <key>typekey>
    110. <string>0string>
    111. dict>
    112. <dict>
    113. <key>pathkey>
    114. <string>0string>
    115. <key>roadkey>
    116. <string>2string>
    117. <key>typekey>
    118. <string>-1string>
    119. dict>
    120. <dict>
    121. <key>pathkey>
    122. <string>1string>
    123. <key>roadkey>
    124. <string>3string>
    125. <key>typekey>
    126. <string>-1string>
    127. dict>
    128. array>
    129. <array>
    130. <dict>
    131. <key>pathkey>
    132. <string>0string>
    133. <key>roadkey>
    134. <string>0string>
    135. <key>typekey>
    136. <string>0string>
    137. dict>
    138. array>
    139. <array>
    140. <dict>
    141. <key>pathkey>
    142. <string>0string>
    143. <key>roadkey>
    144. <string>1string>
    145. <key>typekey>
    146. <string>0string>
    147. dict>
    148. array>
    149. <array>
    150. <dict>
    151. <key>pathkey>
    152. <string>1string>
    153. <key>roadkey>
    154. <string>0string>
    155. <key>typekey>
    156. <string>0string>
    157. dict>
    158. array>
    159. <array>
    160. <dict>
    161. <key>pathkey>
    162. <string>1string>
    163. <key>roadkey>
    164. <string>1string>
    165. <key>typekey>
    166. <string>0string>
    167. dict>
    168. array>
    169. <array>
    170. <dict>
    171. <key>pathkey>
    172. <string>2string>
    173. <key>roadkey>
    174. <string>0string>
    175. <key>typekey>
    176. <string>0string>
    177. dict>
    178. array>
    179. <array>
    180. <dict>
    181. <key>pathkey>
    182. <string>2string>
    183. <key>roadkey>
    184. <string>1string>
    185. <key>typekey>
    186. <string>0string>
    187. dict>
    188. array>
    189. <array>
    190. <dict>
    191. <key>pathkey>
    192. <string>1string>
    193. <key>roadkey>
    194. <string>0string>
    195. <key>typekey>
    196. <string>0string>
    197. dict>
    198. array>
    199. <array>
    200. <dict>
    201. <key>pathkey>
    202. <string>2string>
    203. <key>roadkey>
    204. <string>1string>
    205. <key>typekey>
    206. <string>0string>
    207. dict>
    208. array>
    209. array>
    210. <array>
    211. <array>
    212. <dict>
    213. <key>pathkey>
    214. <string>0string>
    215. <key>roadkey>
    216. <string>0string>
    217. <key>typekey>
    218. <string>0string>
    219. dict>
    220. <dict>
    221. <key>pathkey>
    222. <string>1string>
    223. <key>roadkey>
    224. <string>1string>
    225. <key>typekey>
    226. <string>0string>
    227. dict>
    228. <dict>
    229. <key>pathkey>
    230. <string>0string>
    231. <key>roadkey>
    232. <string>2string>
    233. <key>typekey>
    234. <string>-1string>
    235. dict>
    236. <dict>
    237. <key>pathkey>
    238. <string>1string>
    239. <key>roadkey>
    240. <string>3string>
    241. <key>typekey>
    242. <string>-1string>
    243. dict>
    244. array>
    245. <array>
    246. <dict>
    247. <key>pathkey>
    248. <string>1string>
    249. <key>roadkey>
    250. <string>1string>
    251. <key>typekey>
    252. <string>0string>
    253. dict>
    254. <dict>
    255. <key>pathkey>
    256. <string>2string>
    257. <key>roadkey>
    258. <string>1string>
    259. <key>typekey>
    260. <string>0string>
    261. dict>
    262. array>
    263. <array>
    264. <dict>
    265. <key>pathkey>
    266. <string>0string>
    267. <key>roadkey>
    268. <string>0string>
    269. <key>typekey>
    270. <string>0string>
    271. dict>
    272. <dict>
    273. <key>pathkey>
    274. <string>0string>
    275. <key>roadkey>
    276. <string>1string>
    277. <key>typekey>
    278. <string>0string>
    279. dict>
    280. array>
    281. <array>
    282. <dict>
    283. <key>pathkey>
    284. <string>2string>
    285. <key>roadkey>
    286. <string>0string>
    287. <key>typekey>
    288. <string>0string>
    289. dict>
    290. <dict>
    291. <key>pathkey>
    292. <string>2string>
    293. <key>roadkey>
    294. <string>1string>
    295. <key>typekey>
    296. <string>0string>
    297. dict>
    298. array>
    299. <array>
    300. <dict>
    301. <key>pathkey>
    302. <string>0string>
    303. <key>roadkey>
    304. <string>0string>
    305. <key>typekey>
    306. <string>0string>
    307. dict>
    308. <dict>
    309. <key>pathkey>
    310. <string>1string>
    311. <key>roadkey>
    312. <string>0string>
    313. <key>typekey>
    314. <string>0string>
    315. dict>
    316. array>
    317. <array>
    318. <dict>
    319. <key>pathkey>
    320. <string>1string>
    321. <key>roadkey>
    322. <string>1string>
    323. <key>typekey>
    324. <string>0string>
    325. dict>
    326. <dict>
    327. <key>pathkey>
    328. <string>2string>
    329. <key>roadkey>
    330. <string>0string>
    331. <key>typekey>
    332. <string>0string>
    333. dict>
    334. array>
    335. array>
    336. array>
    337. dict>
    338. plist>

    2.3 怪物信息加载

            可以看到下面的代码实现读取游戏基本信息,然后遍历怪物信息并且保存。

            plist文件的命名规则:level%d_%d_monsters.plist ,第一个数字表示当前第几关,第二个数字表示当前关卡的难度。

    1. // 加载当前等级的数据,包括初始金币,初始血量,当前关卡的怪物波数,怪物信息等。
    2. // 读取plist文件,文件中包含了初始化信息
    3. void BaseMapLayer::loadLevelDataFromePlist()
    4. {
    5. auto fileUtils = FileUtils::getInstance();
    6. std::string file_path = fileUtils->fullPathForFilename(StringUtils::format("plist/level%d_%d_monsters.plist",getLevel(),difficulty_));
    7. if(fileUtils->isFileExist(file_path)){
    8. ValueMap dataMap = fileUtils->getValueMapFromFile(file_path);
    9. auto data_array = dataMap.at("data").asValueVector();
    10. ValueMap data = data_array.at(0).asValueMap();
    11. // 读取初始金币值
    12. startGold_ = data.at("gold").asInt();
    13. maxLife_ = data.at("life").asInt();
    14. totleWave_ = data.at("wave").asInt();
    15. // 怪物信息列表
    16. auto monsters_array = dataMap.at("monsters").asValueVector();
    17. std::vector> thisTimeMonster;
    18. CCLOG("monsters_array size,%zu",monsters_array.size());
    19. // 遍历每一波的信息,monsters_array.size的大小等于
    20. for(auto monsters:monsters_array){
    21. // 每一波,可以分很多次出怪物 ,遍历在当前波的所以次数怪物的信息
    22. for(auto monsters_wave:monsters.asValueVector()){
    23. Vector monsterVector;
    24. // 遍历当前次的怪物信息
    25. auto monsters_wave_lists = monsters_wave.asValueVector();
    26. for (auto item : monsters_wave_lists) {
    27. // 获取当前一波,中每一次出兵时,所以怪物的信息,包括怪物的类型,路线,等
    28. ValueMap monsters_item = item.asValueMap();
    29. monsterVector.pushBack(GroupMonsterNode::initGroupEnemy(
    30. monsters_item.at("type").asInt(),
    31. monsters_item.at("road").asInt(),
    32. monsters_item.at("path").asInt()
    33. ));
    34. }
    35. thisTimeMonster.push_back(monsterVector);
    36. monsters_wave_lists.clear();
    37. }
    38. vector_group_monster_.push_back(thisTimeMonster);
    39. thisTimeMonster.clear();
    40. }
    41. }
    42. else {
    43. CCLOG("文件不存在");
    44. }
    45. }

    2.4 路线信息plist结构体说明

            路线三个array嵌套组成,第一个array:由于每一关的路线可能有多个,因此需要遍历每一条路线的,第二个array:每一波的路线,第三个array:路线坐标。

    2.5 路线信息加载

            安装上面的设计,那么读取的时候肯定是需要遍历三次,依次拿到内容,代码如下:

    1. // 加载怪物移动路径
    2. void BaseMapLayer::loadPathFromPlist()
    3. {
    4. auto fileUtils = FileUtils::getInstance();
    5. std::string file_path = fileUtils->fullPathForFilename(StringUtils::format("plist/level%d_paths.plist",getLevel()));
    6. if(fileUtils->isFileExist(file_path)){
    7. ValueMap dataMap = fileUtils->getValueMapFromFile(file_path);
    8. ValueVector paths_array = dataMap.at("paths").asValueVector();
    9. // 遍历每一关卡中的路线
    10. for(auto wave_item:paths_array){
    11. std::vector> tempPathVector;
    12. auto wave_array = wave_item.asValueVector();
    13. // 遍历每一波的路线
    14. for(auto item : wave_array){
    15. // 遍历每个路线的坐标
    16. std::vector tempRandomPathVector;
    17. for(auto point_array:item.asValueVector()){
    18. auto point_item = point_array.asValueMap();
    19. Point tempPoint= Point();
    20. CCLOG("x:%f,y:%f;",point_item.at("x").asFloat(),point_item.at("y").asFloat());
    21. tempPoint.x = point_item.at("x").asFloat()*1.15;
    22. tempPoint.y = point_item.at("y").asFloat()*1.20+50;
    23. tempRandomPathVector.push_back(tempPoint);
    24. }
    25. tempPathVector.push_back(tempRandomPathVector);
    26. tempRandomPathVector.clear();
    27. }
    28. vector_path_.push_back(tempPathVector);
    29. tempPathVector.clear();
    30. }
    31. }else{
    32. CCLOG("path文件不存在");
    33. }
    34. }

    三、知识点总结

    3.1 写plist文件

        写pilist文件主要有以下两种方式,以map进行存储、以数组方式存储。这里表示都是第一个标签标签中的人第一个标签,

    1. bool FileUtils::writeValueMapToFile(const ValueMap& dict, const std::string& fullPath) const;
    2. bool FileUtils::writeValueVectorToFile(const ValueVector& vecData, const std::string& fullPath) const;
    • 使用writeValueMapToFile写文件。

    代码如下:

    1. void HelloWorld::writePlists1()
    2. {
    3. auto fileUtils = FileUtils::getInstance();
    4. std::string file_path = "/home/uos/Desktop/1.plist";
    5. CCLOG("file_path:%s",file_path.c_str());
    6. if(!fileUtils->isFileExist(file_path)){
    7. ValueMap map;
    8. map["name"] ="张三";
    9. map["age"] =19;
    10. ValueMap map2;
    11. map2["data1"] = "羽毛球";
    12. map2["data2"] = "乒乓球";
    13. map2["data2"] = "足球";
    14. map["tiyu"] = map;
    15. fileUtils->writeValueMapToFile(map,file_path);
    16. }else{
    17. CCLOG("文件已经存在");
    18. }
    19. }

    保存文件的内容如下:

    1. "1.0" encoding="UTF-8"?>
    2. plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"/>
    3. <plist version="1.0">
    4. <dict>
    5. <key>tiyukey>
    6. <dict>
    7. <key>tiyukey>
    8. <dict/>
    9. <key>namekey>
    10. <string>张三string>
    11. <key>agekey>
    12. <integer>19integer>
    13. dict>
    14. <key>namekey>
    15. <string>张三string>
    16. <key>agekey>
    17. <integer>19integer>
    18. dict>
    19. plist>
    • 使用writeValueVectorToFile写文件

    C++代码如下:

    1. void HelloWorld::writePlists2()
    2. {
    3. auto fileUtils = FileUtils::getInstance();
    4. std::string file_path = "/home/uos/Desktop/2.plist";
    5. CCLOG("file_path:%s",file_path.c_str());
    6. if(!fileUtils->isFileExist(file_path)){
    7. ValueVector vectorData;
    8. ValueMap map2;
    9. map2["data1"] = "羽毛球";
    10. map2["data2"] = "乒乓球";
    11. map2["data2"] = "足球";
    12. vectorData.push_back(Value(map2));
    13. vectorData.push_back(Value("Json"));
    14. vectorData.push_back(Value(25));
    15. vectorData.push_back(Value(5.21f));
    16. vectorData.push_back(Value(true));
    17. fileUtils->writeValueVectorToFile(vectorData,file_path);
    18. }else{
    19. CCLOG("文件已经存在");
    20. }
    21. }

    写文件内容如下:

    1. "1.0" encoding="UTF-8"?>
    2. plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"/>
    3. <plist version="1.0">
    4. <array>
    5. <dict>
    6. <key>data2key>
    7. <string>足球string>
    8. <key>data1key>
    9. <string>羽毛球string>
    10. dict>
    11. <string>Jsonstring>
    12. <integer>25integer>
    13. <real>5.2100000real>
    14. <true/>
    15. array>
    16. plist>

    四、文章导航

    上一节:《入门级-Cocos2dx4.0 塔防游戏开发》---第十课:游戏中餐单设置

    下一节:

    总章:《入门级-Cocos2d 4.0塔防游戏开发》---实战_cocos2d开发的游戏

  • 相关阅读:
    Eclipse插件开发demo
    Python 学习 Day44
    LintCode 1359: Convert Sorted Array to Binary Search Tree
    C++动态库制作
    基于jquery 实现导航条高亮显示的两种方法
    烟雾、空气质量、温湿度…自己徒手做个环境检测设备
    FreeSWITCH添加自定义endpoint之媒体交互
    实现Ubuntu与Nvida Nano远程连接
    Android系统启动流程分析
    2022年最后一个月,普通人的翻身机会来了!
  • 原文地址:https://blog.csdn.net/arv002/article/details/132988490