Cocos2d-x Lua 阅读Csv文件,使用数据更方便

摘要:
在我的书或销售之前,我的源代码有一个Csvshadow文件。也许这是偏见。我使用的是Csv,这将是最长的轮廓,所以我不会很喜欢它。Csv文件的格式非常简单,即数据行在字段之间用逗号分隔,也可以使用Excel轻松编辑计划。Csv格式文件。它也很容易分析,所以自己写很快~(小若:我喜欢用它,你做什么)最近,我在用Lua写游戏。对于技能、怪物和其他配置,我仍然选择


在我的书或出售之前,我的源代码,有Csvshadow文件。

也许这是偏见。我与工作将是最长的轮廓Csv,所以,我会帮助不大喜欢它的游戏。

Csv文件,非常格式easy,也就是说,一个数据线,字段之间用逗号分隔,策划也能够方便地使用Excel进行编辑。

Csv格式的文件。解析起来也非常easy,所以自己动手写写非常快~(小若:我就喜欢拿来主义,你怎么着)

近期在用Lua写游戏,对于技能、怪物等配置,我还是选择用Csv~

不得不说,Lua等脚本语言,在某些方面是C++没法比的,这次我就用Csv来表达这种心情~

笨木头花心贡献,哈?花心?不,是用心~

转载请注明,原文地址:http://www.benmutou.com/archives/1634

文章来源:笨木头与游戏开发

 

一份Csv配置文件

我们来看看这样一份Csv文件,如图:

ID,Name,Des,Model
ID,名字,描写叙述,图片模型
1,广告,www.benmutou.com,csv.png
2,否认,呵呵。广告什么的,我才不会加,good.png

(小若:这是图吗?是哪里是图啊!

当然。这样好像不够清晰,我们来这样看看:

mutouCsv

这是非常easy的一个Csv文件:

第一行是英文名字,非常重要,由于在代码里我们要通过这个名字来获取相应的字段内容。

第二行是中文名字,没什么作用,主要是给那些小白看的。比方旁白什么的。(小若:你的比方能不能不要这么有针对性?)

第三和第四行才是真正的内容,通常我都会给第一个字段设定为ID。这样能够依据ID轻松获取到相应行的内容。

Cocos Code IDE

OK,在读取Csv文件之前,略微提一下这个IDE。它是Cocos2d-x官方出的一个IDE。专门针对Cocos2d-x+Lua、Cocos2d-x+JS。但不支持Cocos2d-x+C++。

尽管眼下这个IDE还是RC版本号,我是比較喜欢尝鲜的人。Cocos2d-x3.0版本号我也是从Alpha玩起的~

就那句什么,“有坑才有成长”。我是这么觉得的~

本文也是基于Cocos Code IDE来解说,所以略微提一下,IDE能够到官网下载。随便看看入门指引,几分钟的事情。

然后创建一个项目。

字符串切割

好了,项目创建完之后,默认有个main.lua和GameScene.lua,我们只须要在main.lua里做做測试就能够了

Csv是用逗号切割的,所以,字符串切割功能,不可缺少。Lua似乎没有提供这个功能,幸好,这非常easy。

在mian.lua里main函数前面加入一个函数:

function split(str, reps)
    local resultStrsList = {};
    string.gsub(str, '[^' .. reps ..']+', function(w) table.insert(resultStrsList, w) end );
    return resultStrsList;
end

split有两个參数,str当然就是准备被切割的字符串了,reps又当然是分隔符了~

这里用到了string库的gsub函数。共三个參数:

1. str ,待切割的字符串

2.’[^' .. reps ..']+’,这一看就是那什么,正則表達式。这货我非常少用。所以每次用的时候就翻文档,用完就忘。

这里还比較简单,比方reps是逗号,那么,就变成 ‘[^,]+’  ,这个表达式的意思是:查找非逗号字符。而且多次匹配~

比方“heab,”。前面的heab都不是逗号,全部都匹配了,直到发现了第五个字符。它是逗号,停止匹配。于是终于匹配的字符串是“heab”。

(来自2014.09.17的说明:这里事实上不是正則表達式。而是Lua里的“模式”。跟正則表達式不全然一样,但这里的解释仍然是行得通的,所以不用操心。)

3.每次切割完的字符串都能通过回调函数获取到,w參数就是切割后的一个子字符串,把它保存到一个table

OK,就这么简单,这样就能得到一个table。table里保存了全部被切割的子字符串。

測试一下,把默认的main函数的代码都删了,改成下面这个样子:

local function main()
    local t = split("nihfao,hehe,hen", ",");

    for k, v in pairs(t) do
        print(v);
    end
end


然后按F11执行,输出下面日志:

[LUA-print] nihfao 

[LUA-print] hehe

[LUA-print] hen

成功了~

真正的解析Csv

我们的重点来了,解析Csv文件。

我们不不过要解析。解析完,还要保存起来。方便以后取配置数据~

所以,为了以后更方便地读取数据,我想了一个好办法。

来看看代码,在mian函数的上面再加一个新函数:

function loadCsvFile(filePath) 
    -- 读取文件
    local data = cc.FileUtils:getInstance():getStringFromFile(filePath);

    -- 按行划分
    local lineStr = split(data, '

');

    --[[
                从第3行開始保存(第一行是标题,第二行是凝视,后面的行才是内容) 
            
                用二维数组保存:arr[ID][属性标题字符串]
    ]]
    local titles = split(lineStr[1], ",");
    local ID = 1;
    local arrs = {};
    for i = 3, #lineStr, 1 do
        -- 一行中。每一列的内容
        local content = split(lineStr[i], ",");

        -- 以标题作为索引,保存每一列的内容,取值的时候这样取:arrs[1].Title
        arrs[ID] = {};
        for j = 1, #titles, 1 do
            arrs[ID][titles[j]] = content[j];
        end

        ID = ID + 1;
    end

    return arrs;
end

是不是非常easy?(小若:简单个毛线啊。)

这可比在C++里解析要简单多了~


一句句来分析吧:

1.通过FileUtils的getStringFromFile函数读取文件。取得字符串内容

2.local lineStr = split(data, ‘ ’); 通过split函数,把文件内容按行切割。得到一个lineStr,它存放了每一行的内容

3.local titles = split(lineStr[1], “,”); 还记得我们的Csv文件吗?第一行内容是英文字母,它们非常重要

这里把文件的第一行内容用逗号切割。得到titles,它存放了第一行的每个字段。

这些字段有什么用呢?以后我们将通过这些字段来获取配置数据。

4.接着,新建一个table变量:local arrs = {}; 它将完整地保存解析后的Csv文件数据。

5.接下来有两个for循环。

先来看第一层循环:

for i = 3, #lineStr, 1 do
     — 一行中,每一列的内容
     local content = split(lineStr[i], “,”);

end

非常早之前我们说过了。Csv的第一行是英文字段、第二行是中文解释,第三行才開始是真正的内容~所以我们要从第三行開始。

我们知道。Lua的table下标是从1開始的。于是,i的初始值为3

lineStr里存放的是每一行的内容。所以,第一层的for循环是为了取出每一行的内容,然后按逗号切割。保存到content变量里。

接下来,看第二层循环:

– 以标题作为索引,保存每一列的内容,取值的时候这样取:arrs[1].Title

arrs[ID] = {};
for j = 1, #titles, 1 do
      arrs[ID][titles[j]] = content[j];
end

arrs[ID] = {}是什么意思呢?这代表是一行的内容,arrs[ID]能够看做是一个数组,它保存了某一行的数据。

那么,arrs[ID]数组的下标自然就是我们的英文字母了(也就是之前一直说的,非常重要的第一行内容)。

逻辑有点乱,我们慢慢理解:

尽管content保存了每一行的内容。可是它不方面获取数据,由于它的下标是数字。

所以,我们要把content的内容一个个拷贝到arrs[ID]里。把数字下标全部换成英文字符串。

第二层for循环就是在做这么一件事情。


測试一下

好了,就这么解释肯定还有点混乱吧,来測试一下就知道我倒底在说什么了。

改动main函数内容为:

local function main()
    local csvConfig = loadCsvFile("res/Mutou.Csv");
    
    print(csvConfig[1].Name .. ":" .. csvConfig[1].Des);
    print(csvConfig[2].Name .. ":" .. csvConfig[2].Des);
end


按F11执行。将输出下面日志:

[LUA-print] 广告:www.benmutou.com
[LUA-print] 否认:呵呵,广告什么的。我才不会加

首先,loadCsvFile会解析Csv文件,然后返回解析后的内容。

接着,我想获取ID为1的配置数据,比方,要获取它的Name字段属性,就非常easy了:csvConfig[1].Name 就能够了~

假设你对Lua的table比較生疏的话。你可能会无法理解本文的“精髓”(小若:由于根本就没有精髓啊!)

关于Lua的table。大家能够看看我的这篇文章。相信你会对table有一个初步的了解(足以看懂这篇文章)

巧说table的几种构造方式http://www.benmutou.com/archives/627 

后话

我个人是觉得这么做非常方便。我不是说这么解析非常方便,而是。解析之后,要获取字段值的时候,非常方便~

以后要给配置文件新增字段的话,对于解析和使用都全然没有影响,这是最舒服的地方。

当然了,这就要求我们的配置文件的第一行一定不能写错了。否则就不太好玩了。

假设是在C++里,可能就没法达到这么方便的程度了。尽管也能模仿,通过getValue(“key”)这种方式也行~

但无论怎么说,还是不如脚本来得自然~

尽管它方便,但对于全脚本开发手游。还是不太舒服,有些地方,脚本全然比不上C++(不是指执行效率)~

行,这么多~不要拉仇恨~

版权声明:本文博客原创文章。博客,未经同意,不得转载。

免责声明:文章转载自《Cocos2d-x Lua 阅读Csv文件,使用数据更方便》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇discuz安装步骤localStorage兼容方案下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

网上购物车数据库设计

一、概述 网上购物店的数据模型,它主要模式有产品:product ,帐户:Account,定单:Order。和产品相关的表有category ,product,item, inventory, supplier;和用户相关表有的account ,signon ,profile;和定单相关的表有orders,orderstatus,lineitem FK:...

[ext4]03 磁盘布局 – Flexible group分析

Flexible Block Groups (flex_bg),我称之为“弹性块组”,是EXT4文件系统引入的一个feature。 所谓Flexible Block Groups,就是将连续的多个物理block groups绑在一起组成一个逻辑块组,这个逻辑块组就称之为Flex_group(也就是flex_bg)。 在一个Flex_group中,第一个物理...

Oracle如何迁移、管理、清除Audit数据(AUD$和FGA_LOG$表)

Oracle如何迁移、管理、清除Audit数据(AUD$和FGA_LOG$表) 前言 版本:11.2.0.4.0。 Oracle 11G中没特殊要求还是要建议关闭审计功能:alter system set audit_trail = none scope=spfile  sid='*'; 由于默认审计数据的AUD$和FGA_LOG$表在system表空间,...

el-table设置默认选中

//初始设置选中 toggleSelection(rows){ if(rows){ rows.forEach(row=>{ this.$refs.table.toggleRowSelection(row); }); } } rows传入选中项的集合...

ngx_lua 随笔

--[[ test--]]ngx.header.content_type = "text/plain"; --输出头部local user = ngx.var.arg_user -- 定义user变量并获取url中的参数 http://localhost?user=hellolocal sys = ngx.var.server_name -- 获取ngi...

Mybatis自动生成Xml文件,针对字段类型为text等会默认产生XXXXWithBlobs的方法问题

默认情况下产生的Mapper.xml里面存在: 需要修改generatorConfiguration.xml,里面的table加属性,如: <table domainObjectName="User" tableName="test_user"> <columnOverride column="address" javaTyp...