目录
2.1.1 plist中string标签和array标签的读取
2.1.2 plist中dict、integer、date标签的读取
操作系统:UOS1060专业版本。
cocos2dx:版本4.0
环境搭建教程:统信UOS下配置安装cocos2dx开发环境
本课主要内容:
文章地址:https://arv000.blog.csdn.net/article/details/132988490
地图的构架如下图,所有游戏地图的处理都是一样的,因此可以将其抽象成父类,每一个关卡根据自己的特点进行重载。
Plist文件的结构使用类似xml文件的方式进行编写但是与xml文件又有一些差异。他所使用的标签时固定的有一些几种:string、integer、date、data、true、array、dict。
标签 | 类型 | 说明 |
字符串 | UTF-8编码的字符串 | |
整数 | 十进制数字符串 | |
日期 | ISO8601格式的日期字符串 | |
Base64编码的数据 | ||
真或假 | 标签内没内容 | |
| 数组 | 可以包含任意数量的子元素 |
map |
文件开头前三段几乎是固定的,内容如下:
- "1.0" encoding="UTF-8"?>
- plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
- <plist version="1.0">
读取文件内容函数有一下几个getValueMapFromFile、getValueVectorFromFile
getValueMapFromFile:读取map类型的文件数据对应的
getValueVectorFromFile:读取map类型的文件数据对应的
string标签表示的具体的值的标签,通常为了读取他,我们会在外层套上array标签,表示string数据。plist内容如下:
- "1.0" encoding="UTF-8"?>
- plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
- <plist version="1.0">
- <array>
- <string>苹果string>
- <string>香蕉string>
- <string>雪梨string>
- <string>西瓜string>
- array>
- plist>
C++读取文件内容代码如下:
- void HelloWorld::loadPlists1()
- {
- auto fileUtils = FileUtils::getInstance();
- std::string file_path = fileUtils->fullPathForFilename("demo1.plist");
- if(fileUtils->isFileExist(file_path)){
- ValueVector vectorData = fileUtils->getValueVectorFromFile(file_path);
- for(Value item:vectorData){
- CCLOG("item:%s;\n",item.asString().c_str());
- }
- }else{
- CCLOG("文件不存在");
- }
- }
- "1.0" encoding="UTF-8"?>
- plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
- <plist version="1.0">
- <dict>
- <key>namekey>
- <string>小王string>
- <key>agekey>
- <integer>18integer>
- <key>sexkey>
- <true/>
- <key>CET4key>
- <false />
- <key>coursekey>
- <array>
- <string>语文string>
- <string>数学string>
- <string>计算机string>
- array>
- dict>
- plist>
C++的读取代码如下,需要先读取dict为map类型然后根据关键词去获取他的值。
- void HelloWorld::loadPlists2()
- {
- auto fileUtils = FileUtils::getInstance();
- std::string file_path = fileUtils->fullPathForFilename("demo2.plist");
- if(fileUtils->isFileExist(file_path)){
- ValueMap vectorData = fileUtils->getValueMapFromFile(file_path);
- std::string name = vectorData.at("name").asString();
- int age = vectorData.at("age").asInt();
- bool sex = vectorData.at("sex").asBool();
- bool CET4 = vectorData.at("CET4").asBool();
- ValueVector course = vectorData.at("course").asValueVector();
- CCLOG("name:%s,age:%d,sex:%d,CET4:%d",name.c_str(),age,sex,CET4);
- for(auto item:course){
- CCLOG("item:%s",item.asString().c_str());
- }
-
- }else{
-
- }
- }
测试代码地址:https://download.csdn.net/download/arv002/88359605
在游戏中怪物的派出,是按照波来计算的。每一波中又分好几次派出怪物。每次怪物又有很多的怪物,因此在monster中需要三个array嵌套才能表示。
- "1.0" encoding="UTF-8"?>
- plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
- <plist version="1.0">
- <dict>
- <key>datakey>
- <array>
- <dict>
- <key>goldkey>
- <string>500string>
- <key>lifekey>
- <string>20string>
- <key>wavekey>
- <string>3string>
- dict>
- array>
- <key>monsterskey>
- <array>----- 3波---
- <array> --- 每一波 N 次出怪
- <array> ---- 每次出怪怪物信息列表----
- <dict>
- <key>pathkey>
- <string>0string>
- <key>roadkey>
- <string>0string>
- <key>typekey>
- <string>0string>
- dict>
- <dict>
- <key>pathkey>
- <string>2string>
- <key>roadkey>
- <string>1string>
- <key>typekey>
- <string>0string>
- dict>
- <dict>
- <key>pathkey>
- <string>0string>
- <key>roadkey>
- <string>2string>
- <key>typekey>
- <string>-1string>
- dict>
- <dict>
- <key>pathkey>
- <string>1string>
- <key>roadkey>
- <string>3string>
- <key>typekey>
- <string>-1string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>0string>
- <key>roadkey>
- <string>0string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>0string>
- <key>roadkey>
- <string>1string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>1string>
- <key>roadkey>
- <string>0string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>2string>
- <key>roadkey>
- <string>1string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- array>
- <array>
- <array>
- <dict>
- <key>pathkey>
- <string>0string>
- <key>roadkey>
- <string>0string>
- <key>typekey>
- <string>0string>
- dict>
- <dict>
- <key>pathkey>
- <string>2string>
- <key>roadkey>
- <string>1string>
- <key>typekey>
- <string>0string>
- dict>
- <dict>
- <key>pathkey>
- <string>0string>
- <key>roadkey>
- <string>2string>
- <key>typekey>
- <string>-1string>
- dict>
- <dict>
- <key>pathkey>
- <string>1string>
- <key>roadkey>
- <string>3string>
- <key>typekey>
- <string>-1string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>0string>
- <key>roadkey>
- <string>0string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>0string>
- <key>roadkey>
- <string>1string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>1string>
- <key>roadkey>
- <string>0string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>1string>
- <key>roadkey>
- <string>1string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>2string>
- <key>roadkey>
- <string>0string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>2string>
- <key>roadkey>
- <string>1string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>1string>
- <key>roadkey>
- <string>0string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>2string>
- <key>roadkey>
- <string>1string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- array>
- <array>
- <array>
- <dict>
- <key>pathkey>
- <string>0string>
- <key>roadkey>
- <string>0string>
- <key>typekey>
- <string>0string>
- dict>
- <dict>
- <key>pathkey>
- <string>1string>
- <key>roadkey>
- <string>1string>
- <key>typekey>
- <string>0string>
- dict>
- <dict>
- <key>pathkey>
- <string>0string>
- <key>roadkey>
- <string>2string>
- <key>typekey>
- <string>-1string>
- dict>
- <dict>
- <key>pathkey>
- <string>1string>
- <key>roadkey>
- <string>3string>
- <key>typekey>
- <string>-1string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>1string>
- <key>roadkey>
- <string>1string>
- <key>typekey>
- <string>0string>
- dict>
- <dict>
- <key>pathkey>
- <string>2string>
- <key>roadkey>
- <string>1string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>0string>
- <key>roadkey>
- <string>0string>
- <key>typekey>
- <string>0string>
- dict>
- <dict>
- <key>pathkey>
- <string>0string>
- <key>roadkey>
- <string>1string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>2string>
- <key>roadkey>
- <string>0string>
- <key>typekey>
- <string>0string>
- dict>
- <dict>
- <key>pathkey>
- <string>2string>
- <key>roadkey>
- <string>1string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>0string>
- <key>roadkey>
- <string>0string>
- <key>typekey>
- <string>0string>
- dict>
- <dict>
- <key>pathkey>
- <string>1string>
- <key>roadkey>
- <string>0string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- <array>
- <dict>
- <key>pathkey>
- <string>1string>
- <key>roadkey>
- <string>1string>
- <key>typekey>
- <string>0string>
- dict>
- <dict>
- <key>pathkey>
- <string>2string>
- <key>roadkey>
- <string>0string>
- <key>typekey>
- <string>0string>
- dict>
- array>
- array>
- array>
- dict>
- plist>
可以看到下面的代码实现读取游戏基本信息,然后遍历怪物信息并且保存。
plist文件的命名规则:level%d_%d_monsters.plist ,第一个数字表示当前第几关,第二个数字表示当前关卡的难度。
- // 加载当前等级的数据,包括初始金币,初始血量,当前关卡的怪物波数,怪物信息等。
- // 读取plist文件,文件中包含了初始化信息
- void BaseMapLayer::loadLevelDataFromePlist()
- {
- auto fileUtils = FileUtils::getInstance();
- std::string file_path = fileUtils->fullPathForFilename(StringUtils::format("plist/level%d_%d_monsters.plist",getLevel(),difficulty_));
- if(fileUtils->isFileExist(file_path)){
- ValueMap dataMap = fileUtils->getValueMapFromFile(file_path);
- auto data_array = dataMap.at("data").asValueVector();
- ValueMap data = data_array.at(0).asValueMap();
- // 读取初始金币值
- startGold_ = data.at("gold").asInt();
- maxLife_ = data.at("life").asInt();
- totleWave_ = data.at("wave").asInt();
- // 怪物信息列表
- auto monsters_array = dataMap.at("monsters").asValueVector();
- std::vector
> thisTimeMonster; - CCLOG("monsters_array size,%zu",monsters_array.size());
- // 遍历每一波的信息,monsters_array.size的大小等于
- for(auto monsters:monsters_array){
- // 每一波,可以分很多次出怪物 ,遍历在当前波的所以次数怪物的信息
- for(auto monsters_wave:monsters.asValueVector()){
- Vector
monsterVector; - // 遍历当前次的怪物信息
- auto monsters_wave_lists = monsters_wave.asValueVector();
- for (auto item : monsters_wave_lists) {
- // 获取当前一波,中每一次出兵时,所以怪物的信息,包括怪物的类型,路线,等
- ValueMap monsters_item = item.asValueMap();
- monsterVector.pushBack(GroupMonsterNode::initGroupEnemy(
- monsters_item.at("type").asInt(),
- monsters_item.at("road").asInt(),
- monsters_item.at("path").asInt()
- ));
-
- }
- thisTimeMonster.push_back(monsterVector);
- monsters_wave_lists.clear();
- }
- vector_group_monster_.push_back(thisTimeMonster);
- thisTimeMonster.clear();
- }
- }
- else {
- CCLOG("文件不存在");
- }
- }
路线三个array嵌套组成,第一个array:由于每一关的路线可能有多个,因此需要遍历每一条路线的,第二个array:每一波的路线,第三个array:路线坐标。
安装上面的设计,那么读取的时候肯定是需要遍历三次,依次拿到内容,代码如下:
- // 加载怪物移动路径
- void BaseMapLayer::loadPathFromPlist()
- {
- auto fileUtils = FileUtils::getInstance();
- std::string file_path = fileUtils->fullPathForFilename(StringUtils::format("plist/level%d_paths.plist",getLevel()));
- if(fileUtils->isFileExist(file_path)){
- ValueMap dataMap = fileUtils->getValueMapFromFile(file_path);
- ValueVector paths_array = dataMap.at("paths").asValueVector();
- // 遍历每一关卡中的路线
- for(auto wave_item:paths_array){
- std::vector
> tempPathVector; - auto wave_array = wave_item.asValueVector();
- // 遍历每一波的路线
- for(auto item : wave_array){
- // 遍历每个路线的坐标
- std::vector
tempRandomPathVector; - for(auto point_array:item.asValueVector()){
- auto point_item = point_array.asValueMap();
- Point tempPoint= Point();
- CCLOG("x:%f,y:%f;",point_item.at("x").asFloat(),point_item.at("y").asFloat());
- tempPoint.x = point_item.at("x").asFloat()*1.15;
- tempPoint.y = point_item.at("y").asFloat()*1.20+50;
- tempRandomPathVector.push_back(tempPoint);
- }
- tempPathVector.push_back(tempRandomPathVector);
- tempRandomPathVector.clear();
- }
- vector_path_.push_back(tempPathVector);
- tempPathVector.clear();
- }
- }else{
- CCLOG("path文件不存在");
- }
- }
写pilist文件主要有以下两种方式,以map进行存储、以数组方式存储。这里表示都是第一个标签
- bool FileUtils::writeValueMapToFile(const ValueMap& dict, const std::string& fullPath) const;
- bool FileUtils::writeValueVectorToFile(const ValueVector& vecData, const std::string& fullPath) const;
代码如下:
- void HelloWorld::writePlists1()
- {
- auto fileUtils = FileUtils::getInstance();
- std::string file_path = "/home/uos/Desktop/1.plist";
- CCLOG("file_path:%s",file_path.c_str());
- if(!fileUtils->isFileExist(file_path)){
- ValueMap map;
- map["name"] ="张三";
- map["age"] =19;
-
- ValueMap map2;
- map2["data1"] = "羽毛球";
- map2["data2"] = "乒乓球";
- map2["data2"] = "足球";
- map["tiyu"] = map;
- fileUtils->writeValueMapToFile(map,file_path);
- }else{
- CCLOG("文件已经存在");
- }
- }
保存文件的内容如下:
- "1.0" encoding="UTF-8"?>
- plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"/>
-
- <plist version="1.0">
- <dict>
- <key>tiyukey>
- <dict>
- <key>tiyukey>
- <dict/>
- <key>namekey>
- <string>张三string>
- <key>agekey>
- <integer>19integer>
- dict>
- <key>namekey>
- <string>张三string>
- <key>agekey>
- <integer>19integer>
- dict>
- plist>
C++代码如下:
- void HelloWorld::writePlists2()
- {
- auto fileUtils = FileUtils::getInstance();
- std::string file_path = "/home/uos/Desktop/2.plist";
- CCLOG("file_path:%s",file_path.c_str());
- if(!fileUtils->isFileExist(file_path)){
- ValueVector vectorData;
- ValueMap map2;
- map2["data1"] = "羽毛球";
- map2["data2"] = "乒乓球";
- map2["data2"] = "足球";
- vectorData.push_back(Value(map2));
- vectorData.push_back(Value("Json"));
- vectorData.push_back(Value(25));
- vectorData.push_back(Value(5.21f));
- vectorData.push_back(Value(true));
- fileUtils->writeValueVectorToFile(vectorData,file_path);
- }else{
- CCLOG("文件已经存在");
- }
- }
写文件内容如下:
- "1.0" encoding="UTF-8"?>
- plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"/>
-
- <plist version="1.0">
- <array>
- <dict>
- <key>data2key>
- <string>足球string>
- <key>data1key>
- <string>羽毛球string>
- dict>
- <string>Jsonstring>
- <integer>25integer>
- <real>5.2100000real>
- <true/>
- array>
- plist>
上一节:《入门级-Cocos2dx4.0 塔防游戏开发》---第十课:游戏中餐单设置
下一节: