Lua语言本文章适合有一定数学基础,未深入了解Lua语言的开发者学习。在完成本文章的所有实例后,您将对Lua有一定程度的了解,且能自行独立开发中小型实例。
Lua是一个小巧的弱类型脚本语言。它是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个由Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo三人所组成的研究小组于1993年开发的。 其设计目的是为了通过灵活嵌入应用程序中从而为应用程序提供灵活的扩展和定制功能。Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。Lua并没有提供强大的库,这是由它的定位决定的。所以Lua不适合作为开发独立应用程序的语言。Lua 有一个同时进行的JIT项目,提供在特定平台上的即时编译功能。
Lua脚本可以很容易的被C/C++ 代码调用,也可以反过来调用C/C++的函数,这使得Lua在应用程序中可以被广泛应用。不仅仅作为扩展脚本,也可以作为普通的配置文件,代替XML,ini等文件格式,并且更容易理解和维护。 Lua由标准C编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以编译,运行。一个完整的Lua解释器不过200k,在所有脚本引擎中,Lua的速度是最快的。这一切都决定了Lua是作为嵌入式脚本的最佳选择。
一、Lua的基础数据类型
Lua 是动态类型语言,变量不要类型定义,只需要为变量赋值。 值可以存储在变量中,作为参数传递或结果返回。
Lua 中有 8 个基本类型分别为:nil、boolean、number、string、userdata、function、thread 和 table。
我们可以使用 type 函数测试给定变量或者值的类型:
print(type("Hello world")) --> string
print(type(10.4*3)) --> number
print(type(print)) --> function
print(type(type)) --> function
print(type(true)) --> boolean
print(type(nil)) --> nil
print(type(type(X))) --> string
二、Lua的变量与函数声明
1.局部变量
局部变量使用local保留关键字进行声明,代码如下:
--声明 a 为变量名,变量为"Hello world"字符串。
local a = "Hello world"--输出 a 变量可以使用print()函数方法
print(a)--Hello world 输出后的结果
2.全局变量
Lua中全局变量是默认不使用local关键字声明的变量,代码如下:
--声明 a 变量
a = "Hello world"--打印输出 a 变量
print(a)--Hello world
3.函数声明
函数使用保留关键字function进行声明,旨在后续调用该函数时执行函数内的代码块,代码如下:
--声明函数名为 test 的函数
function test()local a = 'hello world'--声明 a 变量,注意这里声明的是局部变量,因此该变量仅能在此函数中调用。print(a)--打印 a 变量
end
4.注意事项
1.如果一个变量你不在外部函数调用,请将其生成为局部变量,避免变量名重合。
2.声明局部函数步骤同上,在function关键词前加上local即可。
3.在主函数main()中生成的局部变量或全局变量效果是相同的,例如:
local a = 'test'
b = 'test'--此时a和b两个变量的声明范围是一致的
4.一个变量不一定要指向具体的数据类型,也可指向其他变量或函数返回值,例如:
local a = 'test'
local b = a
print(b) --test
三、变量的存储
1.Prop类
使用prop类进行变量存储,代码如下:
local a = { --声明名为a的proptest = 'hello world',test_two = 'hate world'
}
print(a.test) --hello world
print(a.test_two) --hate world
2.table类
代码如下:
local a ={'q','w','e'} --声明名为a的table
print(a[1]) --q 打印变量a为1的索引
print(a[2]) --w 打印变量a为2的索引
print(a[3]) --e 打印变量a为3的索引local b = {['he'] = 'hello world',['be'] = 'hate world'
}
print(b['he']) --hello world
print(b['be']) --hate world
四、函数的参数与返回值
函数声明后可以返回具体的数值或其他函数,同时可以在执行函数是传入具体的参数,代码如下:
function test(a,b) --声明名为test的函数 并声明可向test函数中传入a,b两值local str = a..b --拼接a,b两值print(str) --打印str
end --结束函数test('hello','world')--调用该函数 输出:helloworld
返回值使用return关键词,return可直接结束函数,类似end。
function test()return 'hello world'
end
print(test())--hello world
五、Lua的注释与长字符串的声明
Lua注释使用--进行注释,长注释使用--[[ --]],长字符串使用[==[ ]==](=号两边需相等且大于1个),代码如下:
--test--[[
test
--]]local a = [==[
test
]==]
print(a)--test
六、Lua循环
受限于篇幅,在这里只介绍for循环,学习其他循环可以查阅菜鸟教程。
local a = {'a','b','c'}
for i = 1 , #a do --#a代表a中有多少个变量 类似数学中的card()print(a[i])--分次打印a--输出 a--输出 b--输出
end
七、环境需求
作者在接下来将使用Neverlose作为实例进行介绍。
Neverlose Lua Api
八、Lua判断
判断符:==(等于)、>=(大于等于)、<=(小于等于)、~=(不等于),返回bool值,代码如下:
local a = 0
if a == 0 then --如果a = 0 则print('yes')
elseif a == 2 then--如果a = 2 则print('not yes')
else --如果a 不等于 0 且 a 不等于 2 则print(no)
end
连接符:and(并且)、or(或者),代码如下:
local a = 'a'
if a ~= 's' and a ~='a' thenprint(a)
end
九、Neverlose实例
在这里将举出实例,并写出其运行逻辑与使用的Api,在最后有一些作业,有兴趣的可以完成一下。
1.Hitlogs
API:aim_ack(事件)
逻辑:注册aim_ack事件回调,获取相关实体ID、击中状态与射击数据。
代码如下:
hitgroup_names = {"头", "身体", "胸", "胃部", "左臂", "右臂", "左腿", "右腿", "脖子", "未知部位", "边缘"}
local log_ui_c = ui.create('Hit Logs')
local log_ena = log_ui_c:switch('Enabled')
local log_select = log_ui_c:selectable('Hit Logs Print',{'Chat','Console'})
local log_select_gear = log_select:create()
local log_console_color_picker_true = log_select_gear:color_picker('Console hitlogs hit color')
local log_console_color_picker_false = log_select_gear:color_picker('Console hitlogs empty color')
events.aim_ack:set(function(e)if log_ena:get() thenlocal a = log_select:get()for i = 1 ,#a doif a[i]=='Chat'thenif e.state ~=nil thenprint_chat(' \x0c[QYMY]\x01 你 \x02空了 \x0c'..e.target:get_name()..' \x01的 \x0c'..hitgroup_names[e.wanted_hitgroup]..' \x01原因:\x02'..e.state)elseprint_chat(' \x06[QYMY]\x01 你 \x06命中了 \x0c'..e.target:get_name()..' \x01的 \x0c'..hitgroup_names[e.hitgroup]..' \x01伤害:\x02'..e.damage..' \x01命中几率: \x02'..e.hitchance..' \x01回溯: \x02'..e.backtrack..' Tick')endendif a[i]=='Console'thenif e.state ~=nil thenlocal colord = log_console_color_picker_false:get():to_hex()local color = string.sub(colord,1,6)print_raw('\a'..color..'[QYMY] 你 空了 '..e.target:get_name()..' 的 '..hitgroup_names[e.wanted_hitgroup]..' 原因:'..e.state)elselocal colord = log_console_color_picker_true:get():to_hex()local color = string.sub(colord,1,6)print_raw('\a'..color..'[QYMY] 你 命中了 '..e.target:get_name()..' 的 '..hitgroup_names[e.hitgroup]..' 伤害:'..e.damage..' 命中几率: '..e.hitchance..' 回溯: '..e.backtrack..' Tick')endendendend
end)
十、作业
1.编写使用render渲染事件的击中通知
逻辑:使用render函数渲染文字,在aim_ack事件发生时更新全局变量,使render函数可读,并显示在屏幕上。
2.思考如何在没有3D圆绘制函数的情况下使用三角形完成3D圆的绘制
提示:将圆近似的看做正N边形,使用三角形绘制。