游戏资源自动转换成Lua表

关于这个问题,几年前已经做过一个工具,自动导出成一个c++的struct,然后用vector存储这些数据,然而在实践中发现在遇到多层嵌套时,这种数据表现是非常乏力的。比如掉落表会配多个掉落物,每个掉落物都有数量、概率等。那么最好是将物品ID,数量,概率设置为一个struct然后用一个vector存储,而不是用drop_id1, drop_id2, drop_num1,drop_num2来表示,类似这样的情况是很常见的。后来工作中用Lua比较多,也曾写过一个将表导出lua的工具,对上述问题的解决方案是给每一张表按照需要写一套转换代码生成一张table表。其实也是挺麻烦的。如果给列头设置一些规则,那么可以以尽量少的代码,就自动生成一个lua表出来,那就方便多了。大致分为以下几个步骤:

一、设置列头结构化的规则,比如有数据表player.xlsx数据如下结构

id  name  skill_id  skill_level  skill_id2  skill_level2  buff_id1  buff_id2  reward

401  张三  101    10      102    10      1001    1002    (1002, 20),(1003, 20) 

结构化的规则如下: 

 1 head_struct = {
 2     id = id,
 3     name = name,
 4     skill = {
 5         [1] = {
 6             id = skill_id,
 7             level = skill_level,
 8         },
 9         [2] = {
10             id = skill_id2,
11             level = skill_level2,
12         }
13     },
14     buff = {
15         [1] = buff_id1,
16         [2] = buff_id2,
17     },
18     reward = array(reward , {
19         id = 1,
20         count = 2,
21     }),
22 }

key值为导出后的key值,value值为数据表的列名。array函数将某列的形如(1002, 20),(1003, 20)值转换为reward = { [1] = {id = 1002, count = 20}, [2] = {id = 1003, count = 20}}表结构。这样就基本满足我想要的表现了。

二、将xlsx导出为一个简单的lua table,表名就是取出xlsx的sheet名再上.tmp.lua后缀即可。,上述表就会导出为player.tmp.lua

player = {
    [1] = {
        id = 401,
        name = ‘张三‘,
        skill_id = 101,
        skill_level = 10,
        skill_id2 = 102,
        skill_level2 = 10,
        buff_id1 = 1001,
        buff_id2 = 1002,
        reward = ‘(1002, 20),(1003, 20)‘,
    },
}

要导出为这样的表,还需要给策划设置三个规则:

1.xlsx表第一行默认为列的类型,类型共三种(number, string, bool)可以缩写为n,s,b。为了兼容我自己的情况,如果类型写为int, float, i也会认为是number,其它非number, string, bool 类型的都视为string类型。

2.xlsx表第二行默认为列名。

3.如果某列名为valid,那么true或者1表示为该行数据需要导出,否则表示该行数据不需要导出。

导出代码我是用GO语言写的,代码如下:

  1 /*------------------------------------------------------------------
  2 // 著作版权:Copyright (C) liuxb
  3 // 创建时间:[liuxb|20160704]
  4 // 功能描述:xlsx表导出
  5 //
  6 // 修改时间:
  7 // 修改描述:
  8 //
  9 //----------------------------------------------------------------*/
 10
 11 package main
 12
 13 import (
 14     "flex/log"
 15     "github.com/tealeg/xlsx"
 16     "os"
 17     "strings"
 18     "strconv"
 19 )
 20
 21 type column struct {
 22     name string
 23     type_ string
 24 }
 25
 26 type table struct {
 27     columns []column
 28     rows [][]string
 29 }
 30
 31 var valid string
 32
 33 func init() {
 34     valid = "valid"
 35 }
 36
 37 func getStrings(cells []*xlsx.Cell) []string {
 38     str := make([]string, 0)
 39     for _, cell := range cells {
 40         s, err := cell.String()
 41         if err != nil {
 42             log.Error(err.Error())
 43             s = ""
 44         }
 45         str = append(str, s)
 46     }
 47     return str
 48 }
 49
 50 func getColumn(types []string, names []string) []column {
 51     cols := make([]column, 0)
 52     if len(types)<len(names) {
 53         for i := len(types); i<len(names); i++ {
 54             types = append(types, "s")
 55         }
 56     }
 57     for i := 0; i<len(types); i++ {
 58         types[i] = strings.ToLower(types[i])
 59         switch types[i] {
 60         case "n":
 61         case "i":
 62             types[i] = "n"
 63         case "int":
 64             types[i] = "n"
 65         case "float":
 66             types[i] = "n"
 67         case "number":
 68             types[i] = "n"
 69         case "b":
 70         case "bool":
 71             types[i] = "b"
 72         case "string":
 73             types[i] = "s"
 74         default:
 75             types[i] = "s"
 76         }
 77     }
 78     for i:= 0; i<len(names); i++ {
 79         if names[i] == "" {
 80             break
 81         }
 82         col := column{
 83             name : names[i],
 84             type_: types[i],
 85         }
 86         v := strings.ToLower(col.name)
 87         if v == valid {
 88             col.name = v
 89         }
 90         cols = append(cols, col)
 91     }
 92     return cols
 93 }
 94
 95 func getRow(cols []column, vals []string) []string {
 96     if len(vals)<len(cols) {
 97         for i := len(vals); i<len(cols); i++ {
 98             vals = append(vals, "")
 99         }
100     }
101     if len(vals)>len(cols) {
102         vals = vals[0:len(cols)]
103     }
104     for i:= 0; i<len(cols); i++ {
105         if cols[i].name == valid {
106             v := strings.ToLower(vals[i])
107             if v == "false" || v == "0" {
108                 return nil
109             }
110         }
111     }
112     return vals
113 }
114
115 func getTable(start int, rows []*xlsx.Row) *table {
116     if len(rows)<4 || len(rows)<start {
117         return nil
118     }
119     t := new(table)
120     t.rows = make([][]string, 0)
121
122     types := getStrings(rows[0].Cells)
123     names := getStrings(rows[1].Cells)
124     cols := getColumn(types, names)
125     t.columns = cols
126     for i := start; i<len(rows); i++ {
127         row := getRow(cols, getStrings(rows[i].Cells))
128         if row != nil {
129             t.rows = append(t.rows, row)
130         }
131     }
132     return t
133 }
134
135 func toLuaTable(tableName string, t *table) string {
136     lines := "g_" + tableName + " = {\n"
137     if t!=nil {
138         for id, row := range t.rows {
139             lines = lines + "\t[" + strconv.Itoa(id+1) + "] = {\n"
140             for k, v := range row {
141                 if t.columns[k].name != valid {
142                     line := "\t\t" + t.columns[k].name + " = "
143                     if t.columns[k].type_ == "s" {
144                         line = line + "\"" + v + "\",\n"
145                     }else if t.columns[k].type_ == "b" {
146                         v = strings.ToLower(v)
147                         log.Info("k:%d, v:%s", k, v)
148                         if v == "true" || v == "1" {
149                             v = "true"
150                         }else {
151                             v = "false"
152                         }
153                         line = line + v + ",\n"
154                     }else{
155                         _, err := strconv.ParseFloat(v, 32)
156                         if err != nil {
157                             v = "nil"
158                         }
159                         line = line + v + ",\n"
160                     }
161                     lines = lines + line
162                 }
163             }
164             lines = lines + "\t},\n"
165         }
166     }
167     lines = lines + "}"
168     return lines
169 }
170
171 func main() {
172     log.SetFilename("excel")
173     excelFileName := os.Args[1]
174     start, e := strconv.Atoi(os.Args[2])
175     if e!=nil {
176         log.Error(e.Error())
177         return
178     }
179     xlFile, err := xlsx.OpenFile(excelFileName)
180     if err != nil {
181         log.Error(err.Error())
182         return
183     }
184     for _, sheet := range xlFile.Sheets {
185         fileName := sheet.Name + ".tmp.lua"
186         file, err := os.Create(fileName)
187         if err != nil {
188             log.Error(err.Error())
189             return
190         }
191         t := getTable(start-1, sheet.Rows)
192         luaStr := toLuaTable(sheet.Name, t)
193         file.WriteString(luaStr)
194     }
195 }

其中日志库是自己写的flex/log。

时间: 2024-12-27 10:02:40

游戏资源自动转换成Lua表的相关文章

SQL Server 2005中的分区表(六):将已分区表转换成普通表

在前面,我们介绍过怎么样直接创建一个分区表,也介绍过怎么将一个普通表转换成一个分区表.那么,这两种方式创建的表有什么区别呢?现在,我又最新地创建了两个表: 第一个表名为Sale,这个表使用的是<SQL Server 2005中的分区表(一):什么是分区表?为什么要用分区表?如何创建分区表?>中的方法创建的,在创建完之后,还为该表添加了一个主键. 第二个表名Sale1,这个表使用的是<SQL Server 2005中的分区表(三):将普通表转换成分区表>中的方法创建的,也就是先创建了

poi excel自动转换成javabean 支持引用类型属性二级转换

最近项目需要使用excel导入功能,导入学生的时候需要指定所在班级,使用excel一次性导入! 将以前的代码改改支持属性内引用类的转换. 测试对象为User对象,javabean结构: private String username; private int id; private String name; private Date birthday; private long height; private double salary; private User user; 使用测试代码: M

【游戏开发】Excel表格批量转换成lua的转表工具

一.简介 在上篇博客<[游戏开发]Excel表格批量转换成CSV的小工具> 中,我们介绍了如何将策划提供的Excel表格转换为轻便的CSV文件供开发人员使用.实际在Unity开发中,很多游戏都是使用Lua语言进行开发的.如果要用Lua直接读取CSV文件的话,又要写个对应的CSV解析类,不方便的同时还会影响一些加载速度,牺牲游戏性能.因此我们可以直接将Excel表格转换为lua文件,这样就可以高效.方便地在Lua中使用策划配置的数据了.在本篇博客中,马三将会和大家一起,用C#语言实现一个Exce

记一次踩坑 Gson转换map对象时 Integer类型自动转换成Double类型

之前一直使用json转换map对象,因为公司统一使用gson,我按照网上转换map对象的方式转换: Map<String, Object> params = gson.fromJson(gson.toJson(payMentResultDto), Map.class); 结果对象里Integer类型自动变成double类型... 解决办法: 网上大致有俩种,1.修改源码(能力达不到)2.增加适配器 我找了一下,解决办法有俩种(比较实用) 1.网上看到的(自定义类型适配器),亲测可用 //这俩段

sql纵表转换成横表

数据库中 将一张纵表转换为一张横表 数据库纵表数据 sql语句如下 select cardid, max(case t.projectcode when 'IA-002' then t.result end) as ht, max(case t.projectcode when 'IA-003' then t.result end) as wt, max(case t.projectcode when 'IA-005' then t.result end) as bmi, max(case t.

使用kettle把XML文档转换成数据表结构

 在kettle中Get data from xml 步骤和 XML Input Stream (StAX)步骤读取并解析xml文件.Get data from xml 步骤使用dom方式解析,比较消耗内存,当文件很大时,就不可取.XML Input Stream (StAX)步骤使用完全不同的方式解析大而复杂的文件,且能快速载入数据,所以建议使用该步骤. 下面通过示例来展示如何使用该步骤,源xml文件内容如下: <?xml version="1.0"?> <ti

Mysql 表转换成 Sqlite表

目前的转换仅仅支持对没有外键的Mysql数据表 准备: 下载安装 Sqlite Expert 软件 一 获取Mysql中的.sql文件,获取过程省略可以直接导出sql文件 二 在Sqlite Expert 中新建数据库 三 在数据库中选中sql Tab,导入之前准备sql文件 四 关键步骤 将创建表的最后关于编码的sql语句一句primary key的语句删除 并在主键的创建是修改创建方法 将自动增长删除,这样说有点抽象,如下实例 这是mysql建表方式 CREATE TABLE `admin`

zabbix获取到的数值大于1000之后自动转换成1k

问题:zabbix在取到的值很大时会自动变成K,M,G 解决方法: 1.修改/var/www/html/zabbix/include/func.inc.php文件(这个文件不一定在这,自己find找下) 将$blackList = ['%', 'ms', 'rpm', 'RPM']; 改为$blackList = ['%', 'ms', 'rpm', 'RPM', '条']; 这个'条'是我当前需要的单位,你可以根据自己的需求自定义,比如ge,mm都可以 2.将自己的监控项的单位设置成刚刚新加的

SQL竖表转换成横表统计

#创建表user_score create table user_score ( name varchar(20), subjects varchar(20), score int ); insert into user_score(name,subjects,score) values('张三','语文',60); insert into user_score(name,subjects,score) values('张三','数学',70); insert into user_score(n