介绍
在本章中,我们将讨论Lua中的脚本编写,帮助完成此工作所需的工具以及一些您可能会发现有用的技术。
继承开发环境
具有代码突出显示功能的代码编辑器足以在Lua中编写脚本。代码突出显示会根据单词和字符的表示使用不同的颜色。这使您可以轻松地注意到错误和不一致之处。
例如:
function ctf.post(team,msg)
if not ctf.team(team) then
return false
end
if not ctf.team(team).log then
ctf.team(team).log = {}
end
table.insert(ctf.team(team).log,1,msg)
ctf.save()
return true
end
在这个例子中的关键字高亮显示,包括if
,then
,end
,和return
。默认情况下,Lua随附的功能(如)table.insert
也会突出显示。
非常适合Lua的常用编辑器包括:
也可以使用其他合适的编辑器。
Lua代码
程序流程
程序是一系列依次运行的命令。我们称这些命令为“语句”。程序流是这些语句的执行方式,并且不同类型的流允许您跳过或跳过命令集。
流主要分为三种类型:
- 顺序:一个语句一个接一个地运行,不跳过。
- 选择:根据条件跳过序列。
- 迭代:重复相同的语句,直到满足条件为止。
那么,Lua中的语句是什么样的?
local a = 2 -- Set 'a' to 2
local b = 2 -- Set 'b' to 2
local result = a + b -- Set 'result' to a + b, which is 4
a = a + 10
print("Sum is "..result)
在这个例子中,a
,b
,和result
是变量 。通过使用local
关键字声明局部变量,然后给其一个初始值。本地将在后面讨论,因为它是一个非常重要的概念(称为作用域) 的一部分。
该=
标志意味着分配(赋值) ,这样result = a + b
的手段设定的值result
,它的值a + b
。如变量所见,变量名可以长于一个字符result
。同样值得注意的是,与大多数语言一样,Lua区分大小写 ;A
与a
是不同的变量 。
变量类型(数据类型)
变量将是以下类型之一,并且可以在赋值后更改类型。优良作法是确保变量仅是nil或单个非nil类型。
类型 | 描述 | 例子 |
---|---|---|
Nil | 尚未初始化。变量为空,没有任何值 | local A, D = nil |
Number | 整数或十进制数。 | local A = 4 |
String | 字符串。 | local D = one two three |
Boolean | true或false。 | local is_true = false, local E = (1 == 1) |
Table | 集合。 | 解释如下。 |
Function | 函数(方法)。可能需要输入并可能返回值。 | local result = func(1, 2, 3) |
算术运算符
Lua的运运算符包括:
Symbol | Purpose | Example |
---|---|---|
A + B | 加 | 2 + 2 = 4 |
A - B | 减 | 2 - 10 = -8 |
A * B | 乘 | 2 * 2 = 4 |
A / B | 除 | 100 / 50 = 2 |
A ^ B | 平方 | 2 ^ 2 = 2x2 = 4 |
A … B | 拼接 | “foo” … “bar” = “foobar” |
请注意,这不是一个详尽的清单。它并不包含所有可能的运算符。
选择语句
选择的最基本方法是if语句。例如:
local random_number = math.random(1, 100) -- Between 1 and 100.
if random_number > 50 then
print("Woohoo!")
else
print("No!")
end
这将生成一个介于1到100之间的随机数。然后显示“ Woohoo!”。如果该数字大于50,则打印“否!”。
逻辑运算符
Lua中的逻辑运算符包括:
Symbol | Purpose | Example |
---|---|---|
A == B | 等不 | 1 == 1 (true), 1 == 2 (false) |
A ~= B | 不低于 | 1 ~= 1 (false), 1 ~= 2 (true) |
A > B | 大于 | 5 > 2 (true), 1 > 2 (false), 1 > 1 (false) |
A < B | 小于 | 1 < 3 (true), 3 < 1 (false), 1 < 1 (false) |
A >= B | 大于等于 | 5 >= 5 (true), 5 >= 3 (true), 5 >= 6 (false) |
A <= B | 小于等于 | 3 <= 6 (true), 3 <= 3 (true) |
A and B | 与 | (2 > 1) and (1 == 1) (true), (2 > 3) and (1 == 1) (false) |
A or B | 或 | (2 > 1) or (1 == 2) (true), (2 > 4) or (1 == 3) (false) |
not A | 非 | not (1 == 2) (true), not (1 == 1) (false) |
请注意,它并不包含所有可能的运算符。
也可以合并运算符。例如:
if not A and B then
print("Yay!")
end
打印“是!” 如果A为假而B为真。
逻辑和算术运算符的工作方式相同;它们都接受输入并返回可以存储的值。例如:
local A = 5
local is_equal = (A == 5)
if is_equal then
print("Is equal!")
end
程序设计
编程是解决问题的方法,例如对项目列表进行排序,并将其转变为计算机可以理解的步骤。
教给你编程的逻辑过程超出了本书的范围。但是,以下网站在开发此网站时非常有用:
- Codecademy是学习编写代码的最佳资源之一。它提供了交互式的教程体验。
-
Scratch是一个很好的资源,可以从绝对的基础知识入手,并学习编程所需的解决问题的技术。
Scratch旨在教孩子们 如何编程,它不是一种严肃的编程语言。
变量是局部变量
变量是局部变量还是全局变量决定了可以在何处写入或读取变量。局部变量只能在定义的地方访问。这里有些例子:
-- Accessible from within this script file
local one = 1
function myfunc()
-- Accessible from within this function
local two = one + one
if two == one then
-- Accessible from within this if statement
local three = one + two
end
end
相反,可以从脚本文件中的任何位置以及任何其他mod访问全局变量。
function one()
foo = "bar"
end
function two()
print(dump(foo)) -- Output: "bar"
end
one()
two()
尽可能使用局部变量。Mod最多只能创建一个与Mod同名的全局变量。创建其他全局变量是草率的编码,Minetest将对此发出警告:
Assignment to undeclared global 'foo' inside function at init.lua:2
若要更正此问题,请使用“本地”:
function one()
local foo = "bar"
end
function two()
print(dump(foo)) -- Output: nil
end
one()
two()
请记住,nil表示未初始化 。该变量尚未分配值,不存在或尚未初始化(意味着设置为nil)。
函数是一种特殊类型的变量,但也应设为局部变量,因为其他模块可能具有相同名称的函数。
local function foo(bar)
return bar * 2
end
要允许mod调用您的函数,您应该创建一个与mod相同名称的表,然后向其中添加函数。该表通常称为API表或命名空间。
mymod = {}
function mymod.foo(bar)
return "foo" .. bar
end
-- In another mod, or script:
mymod.foo("foobar")
包括其他Lua脚本
建议在mod中包含其他Lua脚本的方法是使用dofile 。
dofile(minetest.get_modpath("modname") .. "/script.lua")
脚本可以返回一个值,这对于共享私有本地资源非常有用:
-- script.lua
return "Hello world!"
-- init.lua
local ret = dofile(minetest.get_modpath("modname") .. "/script.lua")
print(ret) -- Hello world!
后面的章节将讨论如何最好地为mod拆分代码。