今天和大家分享的是使用cocos2dx引擎如何读取excle文件。在游戏开发中,游戏对象的属性,是写在一张表里面的,例如在红警中,每个兵种的攻击值,升级所需要的经验,造建筑所画的钱,这些都是写在数据表里面的。因为这些数据,数值策划经常要修改这些数值。如果直接硬编码,改动量是很大的,因此我们就把这些数据保存在一张excle表里面或者csv格式的文件中。
我的编译环境是:vs2012+coocs2dx3.6+cocos studio1.6+win7,如果不匹配,那我也没办法。
首先,将数据表转化为json文件。因为cocosdx中,内嵌了rapidjson,这个可以解析json文件。
打开coocs studio,选择:文件-》导入模板表-》选择对应的文件格式。
等到添加进去之后,选择导出json。
具体操作细节,参考这边博客:
http://blog.sina.com.cn/s/blog_ad1675150101fd6d.html
等到json文件制作完成,将它放到res文件下。新建一个数据类:
#ifndef __TOWER_DATE_H__
#define __TOWER_DATE_H__
#include"cocos2d.h"
#include
USING_NS_CC;
using namespace std;
class TowerDate
{
public:
int id;//
const char* name;
int spreed;
int spreedpro;//速度权重
int attack;//攻击
int attackpro;//攻击权重
int ice;
int fire;//攻击火属性
int range;//攻击范围
int type;//攻击类型
public:
TowerDate(void);
~TowerDate(void);
};
#endif
然后定义一个数据转换类:
#ifndef __TOWER_DATE_UNTIL_H__
#define __TOWER_DATE_UNTIL_H__
#include"cocos2d.h"
#include "json/rapidjson.h"
#include "json/document.h"
#include
要注意的是:
map
这里还使用了单例设计模式,如果不了解,请参见我之前写的设计模式中的单例模式。
Cpp文件
#include "TowerDateUntil.h"
//1
TowerDateUntil* TowerDateUntil::instance=new TowerDateUntil();
//1
TowerDateUntil* TowerDateUntil::getInstance()
{
return instance;
}
TowerDateUntil::TowerDateUntil(void)
{
initmapdate();
}
void TowerDateUntil::initmapdate()
{
//2
string filename=cocos2d::FileUtils::getInstance()->getStringFromFile("date1.json");
//3
rapidjson::Document m_doc;
//4
m_doc.Parse<0>(filename.c_str());
string str=filename;
//5
rapidjson::Value &pjson=m_doc["json"];
for(int i=0;i
说明:
1. 这里使用了单例模式的饿汉单例模式,它是线程安全的。
2. 这是coco2dx处理文件的通用工具类。
/**
* Gets string from a file.
*/
virtual std::string getStringFromFile(const std::string& filename);
这是函数的说明
3. 这就是coco2dx内嵌的解析json的工具,使用这个要包含下列头函数:
#include "json/rapidjson.h"
#include "json/document.h"
具体介绍和使用参见这篇博客,值得说明的是,这个框架是腾讯写的,作者经常出现在知乎。
http://blog.csdn.net/elloop/article/details/49908689
4. 这一步要说明的是:Parse这个函数,是个函数模板,源码如下:
//! Parse JSON text from a read-only string.
/*! \tparam parseFlags Combination of ParseFlag (must not contain kParseInsituFlag).
\param str Read-only zero-terminated string to be parsed.
*/
template
GenericDocument& Parse(const Ch* str) {
RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
GenericStringStream
return ParseStream
}
首先传入一个unsigned parseFlags,然后传入文件,这里是字符指针,如果你不是很了解函数模板,还是先去看看相关知识。
还有就是:typedef GenericDocument
6这一步中要注意:这个函数
//!@name String
constCh*GetString()const{ RAPIDJSON_ASSERT(IsString()); return data_.s.str; }
其中
union Data {
String s;
Number n;
Object o;
Array a;
};// 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
struct String {
const Ch* str;
SizeType length;
unsigned hashcode;//!< reserved
};// 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
也就是说,在数据类设置name这个变量时,不能将它设置为string标准库中的变量,只能该设置为字符指针。
7.这里要简单的介绍一下pair容器。这个容器的详细介绍会在之后的文章里面和顺序容器,关联容器一起讲解。
Pair保存两个数据成员,他是一个用来生成特定类型的模板,当创建一个pair时,我们必须提供两个类型名,pair的数据成员将具有对应的类型,这两个类型不要求一样。
Pair的数据成员都是公共的,两个成员分别命名为first何second,可以直接用成员访问符号来访问他们。
其中,make_pair(v1,v2),返回一个用v1hev2初始化的pair,它的类型,从v1和v2反推出来。
还有就是,map要操作insert函数,插入类型必须是pair类型
源码下载: