cocos2dx读取excel文件

时间:2022-09-19 11:00:38

今天和大家分享的是使用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文件下。新建一个数据类:

<span style="font-size:24px;color:#333333;">#ifndef __TOWER_DATE_H__
#define __TOWER_DATE_H__
#include"cocos2d.h"
#include<string>
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</span>

然后定义一个数据转换类:

<span style="font-size:24px;color:#333333;">#ifndef __TOWER_DATE_UNTIL_H__
#define __TOWER_DATE_UNTIL_H__

#include"cocos2d.h"
#include "json/rapidjson.h"
#include "json/document.h"
#include<map>
#include<string>
#include"TowerDate.h"
using namespace std;

USING_NS_CC;

class TowerDateUntil
{
public:
static TowerDateUntil* getInstance();
TowerDate getTowerDate();
private:
static TowerDateUntil* instance;
void initmapdate();
map<int,TowerDate> towermap;
public:
TowerDateUntil(void);
~TowerDateUntil(void);
};
#endif</span>


要注意的是:

map<int,TowerDate> towermap;这一句,一般我们都是这样处理的,将被存储为数据和该数据的id存放在一个映射表里面。这里的int,对应的就是防御塔的id,它和它的数据建立一种映射。

这里还使用了单例设计模式,如果不了解,请参见我之前写的设计模式中的单例模式。

 

Cpp文件

<span style="font-size:24px;color:#333333;">#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<pjson.Capacity();i++)
{
TowerDate d;
rapidjson::Value &temp=pjson[i];
d.id=temp["id"].GetInt();
//6
d.name=temp["name"].GetString();
d.spreed=temp["spreed"].GetInt();
d.spreedpro=temp["spreedpro"].GetInt();
//7
towermap.insert(make_pair(i,d));
}
}
TowerDateUntil::~TowerDateUntil(void)
{
}</span>


说明:

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 <unsigned parseFlags>

GenericDocument& Parse(const Ch* str) {

RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));

GenericStringStream<Encoding> s(str);

return ParseStream<parseFlags>(s);

}

首先传入一个unsigned parseFlags,然后传入文件,这里是字符指针,如果你不是很了解函数模板,还是先去看看相关知识。

还有就是:typedef GenericDocument<UTF8<> > Document;这是一个自定义类型,其中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的数据成员都是公共的,两个成员分别命名为firstsecond,可以直接用成员访问符号来访问他们。

其中,make_pair(v1,v2),返回一个用v1hev2初始化的pair,它的类型,从v1v2反推出来。

还有就是,map要操作insert函数,插入类型必须是pair类型

源码下载: