cocos2dx3.2开发 RPG《Flighting》(三)从Excel表中加载需要的数据

一、前言

在一个游戏里面,需要用到的数据一般都是由游戏策划提供的(这里的策划还是由我自己担任啦哈哈)。什么是需要用到的数据?例如我创建一个角色A,A有他自己的攻击力,防御力,速度等,再创建一个角色B,B也有自己的攻击力,防御力,速度等。每个角色都有一些基础属性,但是对应不同的角色,属性的值有可能不同。我们不可能在代码里面把这些数据写死。最好的办法是从一个文件(通常是Excel表格)中读入数据,这样就方便管理和修改。

二、正文

1.Excel

《Flighting》游戏里面用到了4个Excel表格(在Resource的excel文件夹可以找到)。

HeroMessage:对应不同英雄的各个属性

MonsterMessage:对应不同怪物的各个属性

SkillMessage:对应不同技能的各个属性

StageMessage:对应不同关卡的各个属性

其中一个Excel表基本格式如下图:

格式很简单,基本上一看就知道怎么回事了。

2.下面我们以HeroMessage为例子进行接下来的操作。

我们已经做好我们需要的Excel表格,现在我们的目标是将表格的一条条的信息用一个个对象(bean)保存起来。

这里我也是同样采用了cocostuio提供的数据编辑器。大致的思路是这样的:先用cocostudio的数据编辑器将excel表转成一串JSON字符串。

再在代码里面读取并解析这串字符串,将数据信息用一个对象保存,方便管理。

第一步:数据编辑器的使用

打开cocostudio1.6 -》选择数据管理器-》文件-》导入模板表-》Excel

导入完之后

文件-》导出JSON文件-》确定

成功的话,会得到一个json文件,可以用记事本打开看看。

接下来我们作如下修改,字符串的上一行加入:

{”json“:

在字符串的下一行加入:

}

不清楚的话可以看图:修改前:

修改后:

懂json的人可能知道这是为什么,不懂也没关系,先照着做就好。

第二步:在代码中构造相应的信息保存类(bean)

HeroMessage.h

#ifndef _HEROMESSAGE_H_
#define _HEROMESSAGE_H_
#include <string>
using namespace std;
class HeroMessage{
public:
	int id;//唯一id
	string name;//角色名
	string r_name;//骨骼动画资源名
	string r_png;//骨骼动画png
	string r_plist;//骨骼动画plist
	string r_ExportJson;//骨骼动画ExportJson
	int offset_x;//x的偏移量
	int offset_y;//y的偏移量
	int atk_dis;//攻击距离
	int hp;//生命值
	int atk;//攻击力
	int def;//防御力
	int speed;//移动速度
	double atk_speed;//攻击速度
	bool naima;//是不是牧师
	string bullet;//子弹资源名称
	int skill;//对应的技能id
};
#endif

第三步:信息转换工具HeroMessageUtil

HeroMessageUtil就是负责将Json文件读取并加载相应的信息。再用HeroMessage保存

#ifndef _HMUTIL_H_
#define _HMUTIL_H_
#include "HeroMessage.h"
#include "json/rapidjson.h"
#include "json/document.h"
#include "cocos2d.h"
#include <map>
using namespace cocos2d;

class HeroMessageUtil{
public:
	static HeroMessageUtil* getInstance();
	HeroMessage getMessageById(int id);
	map<int,HeroMessage> getHeroMessageMap();
	HeroMessageUtil();
	~HeroMessageUtil();
private:
	void initHeroMsgMap();
private:
	static HeroMessageUtil* m_instance;
	map<int,HeroMessage> heroMsgMap;
};
#endif

可以看出,除了单例方法,构造函数和析构函数外,有三个函数和一个成员变量需要注意

1. map<int,HeroMessage> heroMsgMap;     这是一个map,键是英雄的唯一id,值是对应的信息对象

2. HeroMessage getMessageById(int id);   通过一个英雄的id,获取其全部信息

map<int,HeroMessage> getHeroMessageMap();
获取英雄信息map

3. void initHeroMsgMap();
初始化英雄信息类,在构造函数中会调用

HeroMessageUtil::HeroMessageUtil(){
	initHeroMsgMap();
}

因此,我们重点关注void initHeroMsgMap()

void HeroMessageUtil::initHeroMsgMap(){
	std::string  jsonStr = cocos2d::FileUtils::getInstance()->getStringFromFile("Json/HeroMessage.json");
	rapidjson::Document _mDoc;

	std::string mstr = jsonStr;
	RETURN_IF(NULL==mstr.c_str()||!mstr.compare(""));
	_mDoc.Parse<0>(mstr.c_str());
	RETURN_IF(_mDoc.HasParseError()||!_mDoc.IsObject());
	const rapidjson::Value &pArr = _mDoc["json"];

	CCLOG("Size = %d",pArr.Capacity());

	for(int i=0;i<pArr.Capacity();++i){
		HeroMessage h;
		const rapidjson::Value &temp = pArr[i];
		int id = temp["id"].GetInt();
		h.id = temp["id"].GetInt();
		h.name = temp["name"].GetString();
		h.r_name = temp["r_name"].GetString();
		h.r_png = temp["r_png"].GetString();
		h.r_plist = temp["r_plist"].GetString();
		h.r_ExportJson = temp["r_ExportJson"].GetString();
		h.offset_x = temp["offset_x"].GetInt();
		h.offset_y = temp["offset_y"].GetInt();
		h.atk_dis = temp["atk_dis"].GetInt();
		h.hp = temp["hp"].GetInt();
		h.atk = temp["atk"].GetInt();
		h.def = temp["def"].GetInt();
		h.speed = temp["speed"].GetInt();
		h.atk_speed = temp["atk_speed"].GetDouble();
		int b = temp["naima"].GetInt();
		h.naima = b==0?false:true;
		h.bullet = temp["bullet_img"].GetString();
		h.skill = temp["skill"].GetInt();
		heroMsgMap.insert(make_pair(id,h));

		CCLOG("h : %s",h.r_png.c_str());
	}
	CCLOG("MapSize = %d",heroMsgMap.size());
	return;
}

这里我们用到的是rapidJson这个api,cocos2dx的附加库里面已经有的。所以我们只需要引入以下两个头文件就好

#include "json/rapidjson.h"
#include "json/document.h"
std::string  jsonStr = cocos2d::FileUtils::getInstance()->getStringFromFile("Json/HeroMessage.json");

读取"Json/HeroMessage.json"这个文件,并将这个文件转成一串string

rapidjson::Document _mDoc;

_mDoc是一个Document对象,可以先暂时理解为一个容器

_mDoc.Parse<0>(mstr.c_str());

将从json文件读取的那串字符串转成一个Document对象

const rapidjson::Value &pArr = _mDoc["json"];

读取_mDoc对应的那个json对象中,键为”json“的那个值,保存的pArr对象中(还记得刚刚对json文件的修改吗,现在得到的pArr对象其实才是真正包含重要数据的)

接下来的for循环就是用来遍历一行一行数据的。(pArr.Capacity可以获取pArr对象中又包含了多少个对象)

HeroMessage h;
const rapidjson::Value &temp = pArr[i];//当前行也是一个Value对象,用temp保存
int id = temp["id"].GetInt();//temp["id"]表示从value对象中搜索键值为"id",并且GetInt方法转换成int
h.id = temp["id"].GetInt();//将解析出来的int保存到我们的目的地——HeroMessage

最后构造好HeroMessage对象之后,记得把它放到map里面

heroMsgMap.insert(make_pair(id,h));

这样我们将excel表里面一行行的数据放到了一个map里面了。

最后贴上HeroMessageUtil两个常用的方法:

map<int,HeroMessage> HeroMessageUtil::getHeroMessageMap(){
	return heroMsgMap;
}

HeroMessage HeroMessageUtil::getMessageById(int id){
	auto it =  heroMsgMap.find(id);
	CCASSERT(it!=heroMsgMap.end(),"can't get hero msg of the id");
	return (*it).second;
}

本节结束。

我的csdn地址:http://blog.csdn.net/hezijian22

邮箱地址:[email protected]

如有问题或指教,欢迎与我交流,谢谢。

时间: 2024-10-19 13:02:04

cocos2dx3.2开发 RPG《Flighting》(三)从Excel表中加载需要的数据的相关文章

浅谈DevExpress&lt;三&gt;:在GridView中加载动态图片

今天的演示效果如下:在GridView中的下拉框中选中一种颜色,则后面的加载相应的图片,如下图: 1. 2. 3. 下面说下实现方法:首先在项目中拉一个GirdControl,在里面创建4列:ID,Name,Color,Image,并将Color和Image分别创建repositoryItemComboBox和repositoryItemPictureEdit控件,如下图: 将一个图片文件夹放到程序的启动目录中: 文件夹中包含如下图片: 接下来进行创建数据模板,先创建一个Datetable,添加

在Excel表中快速输入数据

我们平时在Excel表中总是要输入一些数据(比如:"对","错"等)信息,如果在一列中输入英文的话我们可能还是可以接受的,但是如果输入的中文,那么会不会很累呢?接下来我就告诉大家一个比较简单的办法,如何快速的输入数据: 我们首先打开以个Excel工作表,在该表中我们选择C列:如图1 图1 然后在"Home(开始)"选项中单击Number(数字)段旁边的小箭头:如图2 图2 弹出"format Cells(设置单元格格式)"对话

C++开发Excel的com加载项(一)

当前的项目是为Excel开发一个加载项以实现金融相关的业务,综合很多方面因素考虑后,决定放弃C#,而用C++进行开发.用C++开发Excel加载项目前有两种方式,一是Excel加载项xll,另一种是使用ATL制作com加载项.xll方式的好处是它接近Excel的底层,执行速度很快,而且不需要修改注册表,但使用它的复杂度也较高,需要学习一下其专用的数据结构和api调用方式.我本来打算完全用xll进行开发,只是很可惜卡在最后一步,没能找到用xll的api实现ribbon菜单的方法.com加载项开发起

Android 添加数据到本地Excel表中

由于项目需要,今天学习了一下如何将程序里的数据添加到本地的Excel表中. 下面为学习笔记: 先上效果图: 首先,需要导入jxl.jar包到libs文件夹内. 然后创建Excel表,并往表里添加表头. // 创建excel表. public void createExcel(File file) { WritableSheet ws = null; try { if (!file.exists()) { // 创建表 wwb = Workbook.createWorkbook(file); //

visual studio2010中C#生成的,ArcGIS二次开发的basetool的dll,注册为COM组件tlb文件,并在arcmap中加载使用

写了个标题好长啊~~~~ 这两天又认识了一个新玩意,记录一下下,啦啦啦~~~~~ 话说,认识arcgis快十年了,从桌面版到engine的二次开发,其实不过才认识到它的冰山一角, 它总是能带来很多还未知的东西,实话说,就是如此的热爱着它,因为从来都觉得遨游其中,没有边界~~~~~ arcengine二次开发,这个玩意现在已经不流行了,但是其奥妙和乐趣依然无穷~~~~ 言归: 一. 之前写的basetool,basecommand等类都是在独立的系统中运行的,没有单独注册成过组件在桌面版arcma

Cocos2d-x3.0游戏实例之《别救我》第九篇——从tmx文件中加载关卡怪物

上一篇我们已经制作好tg1.tmx文件了,现在就要使用它了. 笨木头花心贡献,啥?花心?不呢,是用心~ 转载请注明,原文地址: http://www.benmutou.com/blog/archives/944 文章来源:笨木头与游戏开发 很抱歉,我们又要新建2个类了,我已经尽力少新建类了,毕竟是教程,类越多越容易混乱. 我们要新建一个Monster类,以及一个MonsterLayer类,专门添加Monster对象. Monster类 来看看Monster.h文件: #ifndef Monste

用python库openpyxl操作excel,从源excel表中提取信息复制到目标excel表中

现代生活中,我们很难不与excel表打交道,excel表有着易学易用的优点,只是当表中数据量很大,我们又需要从其他表册中复制粘贴一些数据(比如身份证号)的时候,我们会越来越倦怠,毕竟我们不是机器,没法长时间做某种重复性的枯燥操作.想象这样一个场景,我们有个几千行的表要填,需要根据姓名输入其对应的身份证号,但之前我们已经做过一个类似的表,同样的一些人的姓名跟身份证号是完整的,那么我们就需要通过一个个查找姓名,然后把身份证号码复制到我们当前要做的表里去. 当我日复一日重复着这些操作的时候,我都很想有

关于Excel不能显示加载项的问题解决

20160322 Microsoft 2010版本,Excel不显示加载项.(没有截图) 点击 文件->选项->加载项,查看应用程序禁用的加载项,将其在下面选项中启用. 若启用后还是不成功,软件会显示错误信息,按照信息查找缺失的文件VSTO2010安装包(在百度上搜索应该能找到),下载并安装. 安装后重新启动Excel,按照提示开启加载项.搞定.

在 SQL Server 中查询EXCEL 表中的数据遇到的各种问题

原文:在 SQL Server 中查询EXCEL 表中的数据遇到的各种问题 SELECT * FROM OpenDataSource( 'Microsoft.Jet.OLEDB.4.0','Data Source="D:\KK.xls";User ID=Admin;Password=;Extended properties=Excel 5.0')...[Sheet1$] 问题: 消息 15281,级别 16,状态 1,第 1 行 SQL Server 阻止了对组件 'Ad Hoc Di