码迷,mamicode.com
首页 > 其他好文 > 详细

游戏资源自动转换成Lua表

时间:2016-07-04 11:28:27      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:

关于这个问题,几年前已经做过一个工具,自动导出成一个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。

 

游戏资源自动转换成Lua表

标签:

原文地址:http://www.cnblogs.com/liumu1209/p/5639807.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!