这篇主要根据MeoHero这个项目简单介绍Lua的变量和数据类型。
一. 变量声明
-- 局部变量(推荐使用)
local damage = 100 -- 数字
local name = "小悟空" -- 字符串
local is_alive = true -- 布尔值
local point = nil -- 空值
-- 全局变量(不推荐使用)
map_name = "LOL" -- 不使用local的变量为全局变量
二. 基本数据类型
a) 数字(number):
-- 整数
local level = 1
local gold = 500
-- 小数
local attack = 33.5
local move_speed = 310.0
-- 负数
local direction = -180
参考代码:
--造成伤害的倍率(%)
mt.damage_rate = 100
--受到伤害的倍率(%)
mt.damaged_rate = 100
b) 字符串(string):
-- 单引号
local name = 'dragon'
-- 双引号
local title = "魔霸工作室"
-- 多行字符串
local desc = [[
这是一个
多行文本
]]
-- 字符串连接
local full_name = name .. '_' .. title -- 使用..连接字符串
参考代码:
string1 = "dark."
string2 = "sheep"
string3 = ".vip"
-- 使用 .. 进行字符串连接
print("连接字符串",string1..string2..string3)
以上代码执行结果为:
连接字符串 dark.sheep.vip
c) 布尔值(boolean):
local is_alive = true
local is_dead = false
-- 常用于条件判断
if is_alive then
-- 执行代码
end
参考代码:
--存活
mt._is_alive = true
d) nil(空值):
-- 未初始化的变量默认为nil
local var
print(var) -- 输出:nil
-- 可以显式设置为nil
local player = nil
参考代码:
mt.handle = 0
三. 复杂数据类型
a) 表(table) - Lua中最重要的数据结构:
-- 数组形式的表
local skills = {'龟派气功', '如意棒', '筋斗云', '狂暴'}
-- 字典形式的表
local hero_data = {
name = "小悟空",
hp = 1000,
mp = 600,
skills = skills
}
-- 访问表
print(skills[1]) -- 访问数组元素
print(hero_data.name) -- 访问字典元素
print(hero_data['hp']) -- 另一种访问字典元素的方式
b) 函数(function):
-- 函数定义
local function add_buff(unit, buff_name, duration)
-- 函数实现
end
-- 匿名函数
local callback = function(event)
print(event)
end
-- 函数作为参数
hero:event('单位-死亡', function()
-- 处理死亡事件
end)
参考代码:
--死亡
--杀死单位
-- [致死伤害]
function mt:kill(killer)
if not self:is_alive() then
return false
end
if not killer then
killer = self
end
self._is_alive = false
self:set('生命', 0)
if not self:is_dummy() then
jass.KillUnit(self.handle)
killer:event_notify('单位-杀死单位', killer, self)
self:event_notify('单位-死亡', self, killer)
end
--打断施法
self:cast_stop()
--删除Buff
if self.buffs then
local buffs = {}
for bff in pairs(self.buffs) do
if not bff.keep then
buffs[#buffs + 1] = bff
end
end
for i = 1, #buffs do
buffs[i]:remove()
end
end
if self:is_illusion() then
self:remove()
elseif not self:is_hero() then
self:wait_to_remove()
end
return true
end
四. 变量作用域
-- 全局变量
map_name = "LOL" -- 可以在任何地方访问
-- 局部变量
local function test()
local x = 1 -- 只在函数内部可见
y = 2 -- 全局变量,不推荐
end
-- 块作用域
do
local block_var = 100 -- 只在do...end块内可见
end
五. 命名规范(从项目中总结):
-- 小写字母加下划线(推荐)
local unit_type = "hero"
local move_speed = 310
-- 驼峰命名(用于类名或重要结构)
local function CreateHero()
end
-- 常量(全大写)
local MAX_LEVEL = 25
local DEFAULT_HP = 1000
重要提示:
- 推荐使用local声明局部变量
- 变量名应该清晰表达其用途
- 注意变量的作用域
- 合理使用注释说明变量的用途
- 遵循项目的命名规范
延伸阅读:变量使用规则(摘取自B站UP主Aaaaaya゚的文章)
可以包含字母、数字、下划线,但不能以数字开头。
例:
a1 = 1 -- 1a = 1 -- 其中 1a会报错,并且无法成功赋值。
变量名区分大小写,即x与X是完全不同的两个变量。
例:
x = 1 X = 2 print(x, X) -- 输出结果:1, 2
变量名的长度没有任何限制。
例:
abcdefghijklmnopqrstuvwxyz = 1 print(abcdefghijklmnopqrstuvwxyz) -- 输入结果:1
变量不需要去声明类型,jass里需要以类型+名称的方式来声明。
例:
// integer是jass里的整数类型 Jass:integer num = 1
-- 无需类型即可直接声明
Lua:num = 1
变量可以在任何地方声明且赋值。
lua的变量想在哪里写就在哪里写,而jass不同。
jass里全局变量需要在globals范围内声明,局部变量必须在函数内顶部声明。例:
全局变量: globals integer num endglobals
局部变量: function init takes nothing returns nothing // 必须在函数内先置顶声明,否则报错无法运行 local integer num num = 1 // 再赋值 endfunction
全局变量可以不用声明便可以直接使用,但会直接返还为nil。
例:
print(num) -- 输出结果:nil
nil等于jass里的null,等于触发器里的没有单位、没有技能、没有XX。也可以理解为空。
变量可以被重新声明为新的类型。
例:
local num = 1 print(num) -- 输出结果:1
local num = ‘王大锤’ print(num) -- 输出结果:王大锤
但这样反复的重新声明为新的类型,在地图代码逐渐增多之后,会导致你根本记不清当前变量到底是什么类型,所以尽可能的避免且少用重新声明。