cocos2d-x学习笔记——Csv文件读取工具
2015-06-17 19:26
495 查看
在一个游戏中,通常会有很多怪物,以及怪物的生命值,魔法值等属性数据,这些数据不可能在代码里面写死,一般都会用配置文件来保存,使用时再加载到内存。
我们常用的配置文件是CSV文件,即逗号分隔值(Comma-Separated Values),如下图所示。
![](http://img.blog.csdn.net/20150617190339216)
今天,我就来介绍一个来读取CSV文件的工具类——MyCsvUtil。
在接受读取CSV文件工具类之前,先介绍一个读取字符串的工具类——StringUtil。
上面那个字符串工具类,最主要的就是一个split函数,因为已经写了足够多的注释了,这里就不再多做解释了。以后要进行字符串读取的话只需要将这个头文件包含进去,再调用split函数就行了。
这个CsvData类比较简单,不必多说了,只需要注意的是getRowColNum这个函数。这个函数是获取Csv文件的规模,即行数和列数(行号和列号都是从0开始的)。
因为Csv文件保存的就是每一行的数据,所以Csv的size大小就是行的数量,要求列数的话,就求Csv文件第0行的数据的个数,得到列的数量。
然后,然后就是真正的编写Csv文件读取工具类啦!
最后,我们就可以在其他的程序里面包含这个Csv文件读取工具类的头文件,就可以使用它了。
这是我在调试模式下测试的结果:
输出结果:
我们常用的配置文件是CSV文件,即逗号分隔值(Comma-Separated Values),如下图所示。
今天,我就来介绍一个来读取CSV文件的工具类——MyCsvUtil。
在接受读取CSV文件工具类之前,先介绍一个读取字符串的工具类——StringUtil。
//头文件StringUtil.h #ifndef __StringUtil_H_ #define __StringUtil_H_ #include "cocos2d.h" class StringUtil : public cocos2d::Ref { public: static StringUtil * getInstance(); virtual bool init(); //用分隔符分割字符窜,结果存放到一个列表中,列表中的对象为Value cocos2d::ValueVector split(const char * srcStr, const char * sSep); private: static StringUtil * m_StringUtil;//Util 是工具的意思! }; //函数实现文件 #include "StringUtil.h" USING_NS_CC; //初始化 StringUtil * StringUtil::m_StringUtil = nullptr; StringUtil * StringUtil::getInstance() { if (m_StringUtil == nullptr) { m_StringUtil = new StringUtil(); if (m_StringUtil && m_StringUtil->init() ) { m_StringUtil->autorelease(); m_StringUtil->retain(); } else { CC_SAFE_DELETE(m_StringUtil); m_StringUtil = nullptr; } } return m_StringUtil; } bool StringUtil::init() { ////拆分字符串 //auto strsList = StringUtil::getInstance()->split("zhaolong,want,to,work!",","); //for (auto str : strsList) //{ // log("str = %s",str.asString().c_str()); //} return true; } //分离函数,srcStr是要进行分离的字符串,sSep是分隔符 separator ValueVector StringUtil::split(const char * srcStr, const char * sSep) { ValueVector stringList; //typedef std::vector<Value> ValueVector; int size = strlen(srcStr); //将数据转换为字符串对象 Value str = Value(srcStr); int startIndex = 0; int endIndex = 0; endIndex = str.asString().find(sSep); std::string lineStr; //根据分隔符拆分字符串,并添加到列表中 while (endIndex > 0) { //拆分的字符串 //substr函数的作用是从给定的字符表达式或备注字段中返回一个子字符串。 lineStr = str.asString().substr(startIndex,endIndex); //放入列表中 stringList.push_back(Value(lineStr)); //更新要分离的字符串 str = Value(str.asString().substr(endIndex + 1,size)); //更新索引号 endIndex = str.asString().find(sSep); } //剩下的字符串也添加进入列表 //将剩下的字符串与空字符串相比,若不为空 if (str.asString().compare("") != 0) { //就把该字符串放入到列表中 stringList.push_back(Value(str.asString())); } return stringList; } #endif
上面那个字符串工具类,最主要的就是一个split函数,因为已经写了足够多的注释了,这里就不再多做解释了。以后要进行字符串读取的话只需要将这个头文件包含进去,再调用split函数就行了。
下面开始讲解真正的Csv文件读取类
我们要想更好的处理和保存csv文件数据,我们应该把它当作对象来处理,新建一个CsvData类,他的类对象就代表一份Csv文件数据。//头文件CsvData.h #ifndef __CsvData_H_ #define __CsvData_H_ #include "cocos2d.h" class CsvData : public cocos2d::Ref { public: CREATE_FUNC(CsvData); virtual bool init(); //添加一行数据 void addLineData(cocos2d::ValueVector lineData); //获取某行的数据 cocos2d::ValueVector getSingleLineData(int iLine); //获取行列大小 cocos2d::Size getRowColNum(); private: //用来存放Csv文件所有行的数据 cocos2d::ValueVector m_allLinesVec; }; //函数实现文件 #include "CsvData.h" USING_NS_CC; bool CsvData::init() { return true; } void CsvData::addLineData(ValueVector lineData) { m_allLinesVec.push_back(Value(lineData)); } ValueVector CsvData::getSingleLineData(int iLine) { return m_allLinesVec.at(iLine).asValueVector(); } Size CsvData::getRowColNum() { Size size = Size(); //获得Csv文件的行数,因为m_allLinesVec变量保存的就是每一行的数据,所以m_allLinesVec的大小就是行的数量 size.width = m_allLinesVec.size(); //如果Csv文件中的行数大于0 if (size.width > 0) { //就求Csv文件第0行的数据的个数,得到列的数量 size.height = m_allLinesVec.at(0).asValueVector().size(); } return size; } #endif
这个CsvData类比较简单,不必多说了,只需要注意的是getRowColNum这个函数。这个函数是获取Csv文件的规模,即行数和列数(行号和列号都是从0开始的)。
因为Csv文件保存的就是每一行的数据,所以Csv的size大小就是行的数量,要求列数的话,就求Csv文件第0行的数据的个数,得到列的数量。
然后,然后就是真正的编写Csv文件读取工具类啦!
//头文件MyCsvUtil.h #ifndef __MyCsvUtil_H_ #define __MyCsvUtil_H_ #include "CsvData.h" class MyCsvUtil : public cocos2d::Ref { public: static MyCsvUtil * getInstance(); virtual bool init(); //加载配置文件 void loadFile(const char * sPath); //获取某行某列的值 cocos2d::Value getValue(int iRow, int iCol, const char * csvFilePath); //获取值并转化为字符串 const std::string getStr(int iRow, int iCol, const char * csvFilePath); //获取值并转换为整形 const int getInt(int iRow, int iCol, const char * csvFilePath); //获取文件的行和列的数量 const cocos2d::Size getFileSize(const char * csvFilePath); private: static MyCsvUtil * ms_CsvUtil; cocos2d::Map<std::string, CsvData *> m_CsvMap; }; #endif //函数实现文件 #include "MyCsvUtil.h" #include "StringUtil.h" USING_NS_CC; MyCsvUtil * MyCsvUtil::ms_CsvUtil = nullptr; MyCsvUtil * MyCsvUtil::getInstance() { if (ms_CsvUtil == nullptr) { ms_CsvUtil = new MyCsvUtil(); if (ms_CsvUtil && ms_CsvUtil->init() ) { ms_CsvUtil->autorelease(); ms_CsvUtil->retain(); } else { CC_SAFE_DELETE(ms_CsvUtil); ms_CsvUtil = nullptr; } } return ms_CsvUtil; } bool MyCsvUtil::init() { if (!TBack::init()) { return false; } return true; } //加载文件 void MyCsvUtil::loadFile(const char * sPath) { //存放一个csv文件的对象 CsvData * csvData = CsvData::create(); //读取路径所在文件的数据,保存到列表中 std::string str = FileUtils::getInstance()->getStringFromFile(sPath); //将得到的数据按换行符分开,放到列表中 ValueVector linesList = StringUtil::getInstance()->split(str.c_str(),"\n"); //把每一行的字符拆分开来(按都好分隔) for (auto value : linesList) { //将一行的字符串按逗号分隔,然后存放到列表中,最后将列表存放到CsvData对象里 //换句话说,csvData将成为一个二维表格,记录了配置文件行和列的字符串 ValueVector tArr = StringUtil::getInstance()->split(value.asString().c_str(),","); csvData->addLineData(tArr); } //将CsvData对象添加到字典里 m_CsvMap.insert(sPath,csvData); } //获取文件规格 const Size MyCsvUtil::getFileSize(const char * csvFilePath) { //取出配置文件的二维表格 auto csvData = m_CsvMap.at(csvFilePath); //如果配置文件不存在,则加载配置文件 if (csvData == nullptr) { loadFile(csvFilePath); csvData = m_CsvMap.at(csvFilePath); } //调用了csvData类的函数 Size size = csvData->getRowColNum(); return size; } //获取文件某行某列 Value MyCsvUtil::getValue(int iRow, int iCol, const char * csvFilePath) { auto csvData = m_CsvMap.at(csvFilePath); if (csvData == nullptr) { loadFile(csvFilePath); csvData = m_CsvMap.at(csvFilePath); } //获取第iRow行数据 ValueVector rowVector = csvData->getSingleLineData(iRow); //获取第iCol列数据 Value colValue = rowVector.at(iCol); return colValue; } //获取文件某行某列并转换为字符串 const std::string MyCsvUtil::getStr(int iRow, int iCol, const char * csvFilePath) { Value val = Value(); val = getValue(iCol,iCol,csvFilePath); return val.asString(); } //获取文件某行某列并转换为整型 const int MyCsvUtil::getInt(int iRow, int iCol, const char * csvFilePath) { Value val = Value(); val = getValue(iRow,iCol,csvFilePath); return val.asInt(); }
最后,我们就可以在其他的程序里面包含这个Csv文件读取工具类的头文件,就可以使用它了。
这是我在调试模式下测试的结果:
#include "MyCsvUtil.h" /*------测试代码段-------*/ const char * sPath = "monster.csv";//文件路径 MyCsvUtil::getInstance()->loadFile(sPath);//加载文件 //获得第1行第1列数据 Value firstMonsterName = MyCsvUtil::getInstance()->getValue(1,1,sPath); //获得第2行第1列数据 Value secMonsterName = MyCsvUtil::getInstance()->getValue(2,1,sPath); //打印结果 log("%s",firstMonsterName.asString().c_str()); log("%s",secMonsterName.asString().c_str());
输出结果:
相关文章推荐
- cocos2d-x 速度变化
- cocos2dx3.2 win7 的android版本编译及调试
- cocospod 之bug
- cocostudio使用plist创建序列帧动画图片名称序列错乱的问题
- Cocos2dx切换场景和资源崩溃的那些事
- cocos2d-x类型转换(CCstring int string char UTF-8互转)
- cocoStudio: Button三种状态切换
- cocos2d-x2.2.3和android平台环境的搭建
- cocos2d-x-2.2.3和vs2012环境配置
- cocos2d-x安装
- cocos2dx lua 接微博SDK(三)--获取用户信息,好友信息
- (转)像素完美碰撞检测(使用cocos2d-x)
- 解决cocos2dx在Xcode中运行时报:convert: iCCP: known incorrect sRGB profile 的问题
- quick-cocos2d-x游戏开发——StateMachine状态机
- Cocos2d-x 2.2.2版本CCEditbox 遇到的bug
- cocos2d 2.2.6 win7下的配置
- cocos2dx 常见的49中动作
- Cocos2d-x的学习之旅(六)输入框
- cocos2dx的内存管理机制
- Cocos2d-x 3.x学习笔记(一):开始Cocos2d之旅