这篇主要根据MeoHero项目简单介绍Lua中字符串和数组的知识。

一、字符串

  1. 字符串的定义方式:

    -- 单引号
    local name = 'small monkey'
    
    -- 双引号
    local skill = "龟派气功"
    
    -- 长字符串(用于多行文本)
    local desc = [[
    这是一个
    多行的技能描述
    很长很长...
    ]]
  2. 字符串连接

    -- 使用 .. 连接字符串
    local hero_name = "小悟空"
    local level = 10
    -- 方式1:直接连接
    local text = hero_name .. "达到了" .. level .. "级"
    
    -- 方式2:使用string.format(推荐)
    local text = string.format("%s达到了%d级", hero_name, level)

从项目代码看实际应用:

--改玩家名字
hero:get_owner():setName(('%s(%s)'):format(hero:get_owner():get_name(), hero:get_name()))

--发送消息
player:sendMsg(('你将在 |cffffff00%d|r 秒后复活'):format(time))
  1. 常用字符串操作:

    -- 获取长度
    local name = "小悟空"
    local length = #name  -- 3(中文字符)
    
    -- 转换大小写
    local text = "Hello"
    local upper = string.upper(text)  -- "HELLO"
    local lower = string.lower(text)  -- "hello"
    
    -- 查找子串
    local str = "我的技能是龟派气功"
    local pos = string.find(str, "龟派气功")  -- 返回位置
    
    -- 替换字符串
    local str = "我要使用龟派气功"
    local new_str = string.gsub(str, "龟派气功", "如意棒")
    
    -- 截取子串
    local str = "小悟空"
    local sub = string.sub(str, 2, 3)  -- "悟空"

二、数组(在Lua中用表实现)

  1. 数组的定义:

    -- 普通数组
    local skills = {'龟派气功', '如意棒', '筋斗云', '狂暴'}
    
    -- 从1开始的索引(Lua的特点)
    print(skills[1])  -- 输出:"龟派气功"
    
    -- 创建指定大小的数组
    local arr = {}
    for i = 1, 5 do
     arr[i] = 0
    end

从项目代码看实际应用:

for i = 1, 16 do
    local p = ac.player(i)
    p.ability_list = {}
    if i <= 10 then
        p.ability_list['英雄'] = {size = 4}
        p.ability_list['学习'] = {size = 4}
        p.ability_list['智能施法'] = {size = 4}
        for x = 1, p.ability_list['英雄'].size do
            p.ability_list['英雄'][x] = ('A0%d%d'):format(i - 1, x - 1)
        end
    end
end
  1. 数组操作:

    -- 添加元素(在末尾)
    local arr = {'A', 'B'}
    table.insert(arr, 'C')  -- arr变成{'A', 'B', 'C'}
    
    -- 指定位置插入
    table.insert(arr, 2, 'X')  -- arr变成{'A', 'X', 'B', 'C'}
    
    -- 删除元素
    table.remove(arr, 2)  -- 删除位置2的元素
    
    -- 获取数组长度
    local length = #arr

从项目代码看实际应用:

--注册技能
data.skill_datas = {}
if type(data.skill_names) == 'string' then
    for name in data.skill_names:gmatch '%S+' do
        table.insert(data.skill_datas, ac.skill[name])
    end
elseif type(data.skill_names) == 'table' then
    for _, name in ipairs(data.skill_names) do
        table.insert(data.skill_datas, ac.skill[name])
    end
end
  1. 数组遍历:

    -- 使用ipairs(推荐,按顺序遍历)
    local heroes = {'小悟空', '惠惠', '雷姆'}
    for index, name in ipairs(heroes) do
     print(index, name)
    end
    
    -- 使用数字索引遍历
    for i = 1, #heroes do
     print(i, heroes[i])
    end
  2. 多维数组:

    -- 二维数组
    local grid = {
     {1, 2, 3},
     {4, 5, 6},
     {7, 8, 9}
    }
    
    -- 访问元素
    print(grid[1][2])  -- 输出:2
    
    -- 创建二维数组
    local map = {}
    for i = 1, 5 do
     map[i] = {}
     for j = 1, 5 do
         map[i][j] = 0
     end
    end
  3. 一些实用技巧:

a) 数组拷贝:

-- 浅拷贝
local function copy_array(arr)
    local new_arr = {}
    for i, v in ipairs(arr) do
        new_arr[i] = v
    end
    return new_arr
end

b) 数组合并:

-- 合并两个数组
local function merge_arrays(arr1, arr2)
    local result = {}
    for _, v in ipairs(arr1) do
        table.insert(result, v)
    end
    for _, v in ipairs(arr2) do
        table.insert(result, v)
    end
    return result
end

c) 数组查找:

-- 查找元素
local function find_element(arr, element)
    for i, v in ipairs(arr) do
        if v == element then
            return i
        end
    end
    return nil
end

重要提示:

  1. 字符串注意事项:
  2. 字符串是不可变的,每次修改都会创建新字符串
  3. 频繁的字符串连接应该使用table.concat
  4. 使用string.format可以让代码更清晰
  5. 数组注意事项:
  6. Lua的数组索引从1开始
  7. 使用#获取长度时要注意中间不能有nil值
  8. ipairs用于数组,pairs用于表
  9. table.insert和table.remove效率不高,频繁操作考虑其他方式

这些知识在游戏开发中经常用于:

  • 技能名称和描述的处理
  • 玩家名字的处理
  • 技能列表的管理
  • 物品栏的实现
  • 地图数据的存储