
了解Lua的基本工作原理以及一些编程的基本构建模块。 这是本系列的第一篇指南。 简介 本指南专为那些在LUA脚本方面经验有限的人设计。它将回顾代码格式化的基础知识、作为代码基础的构建模块,并提供一些示例。本指南旨在让你动手实践,因此你应该打开《桌面模拟器》并启动你的LUA编辑器来跟随操作。 这是本系列的第一篇指南。第二篇是《学习更多Lua知识》。第三篇是名为《学习Lua函数》的实用函数集合。 开始输入前 首先,如果你打算在《桌面模拟器》中编写脚本,我强烈建议你安装Atom。它知道可以使用哪些函数,并会将代码导入/导出到TypeScript中。 关于Atom[berserk-games.com]的安装和设置说明 接下来,你应该将文档知识库[berserk-games.com]添加为书签。一旦开始编写自己的脚本,你会经常参考这个网站。这是你查找《桌面模拟器》特定函数及其工作方式的地方。根据我的经验,你最常使用的是API和对象页面。 设置步骤 当你在《桌面模拟器》中保存脚本时,它会使用你最近的存档,然后将脚本加载到其中。因此,对于任何你打算编写的脚本,你需要执行以下操作:

按你想要的方式设置桌子。 保存桌子。 加载桌子。 在本练习中,取一张空白桌子,生成两个物体(我用了一个方形方块和一个矩形方块)以及一个红色棋子。 记得保存/加载,然后在Atom中打开脚本,或在《桌面模拟器》中通过“主机 > 脚本”开始。 1) Global.lua

Global.lua 是脚本文件,是存档的一部分。在本教程的大部分内容中,我们都将使用它。新存档中,编辑器里总会预先保存一些文本。直接删除即可,我们不会用到这些内容。 也可以编写脚本并将其附加到物体上,而非 Global。这样一来,保存物体时,其 LUA 脚本也会一并保存。大多数功能既可以通过 Global 脚本实现,也可以通过物品脚本实现,但我们将使用 Global 脚本。 2) 函数

函数[berserk-games.com]是触发代码组的元素。其中一些内置于脚本系统(例如onload()),而另一些可由用户创建。每个函数都以“function”一词开头,以“end”一词结尾。 《桌面模拟器》中一个常见的内置函数是onload()。此函数在每次加载脚本时触发(例如按下撤销/重做按钮时)。那么我们就从使用它来激活我们将要创建的函数开始吧。函数应以小写字母开头,且不能包含空格。我们将使用exampleFunction。 function onload() exampleFunction() end 现在,我们的脚本在加载时会尝试运行一个名为exampleFunction的函数。但我们还没有编写这个函数!现在,我们将在onload函数结束后创建自己的函数。 function exampleFunction() print('Hello, World.') end print()命令也是一个函数。不过它并非触发LUA中的某段代码,而是激活《桌面模拟器》内部的程序以产生期望的效果。在这个例子中,它会在聊天框中向游戏主机发送一条消息。 这条消息被称为字符串,通常用引号括起来以示区分。字符串是一系列字符。(例如:"这是一个字符串。" 或 '这个也是!') 当你保存并上传脚本后,它现在应该会在聊天框中显示"Hello, World."。 拓展内容:创建自己的函数时,你还可以向其传递变量供函数使用。另一种编写初始练习的方式如下: function onload() exampleFunction('Hello, World.') end function exampleFunction(passedString) print(passedString) end 我们创建了一个变量来表示该字符串(passedString),然后打印了该变量中包含的内容。 3) 对象

Objects[berserk-games.com]是桌面环境中存在的实体。在我们的示例中,当前的对象是两个方块和一个跳棋(我们正在制作的游戏可真不怎么样)。通过脚本,我们可以操控这些对象,移动它们、为其添加按钮或执行其他各种操作。我们要重新开始编写Global.lua,先删除其中的所有文本。 GUID要对某个对象进行操作,首先必须在LUA中对其进行识别。有多种识别方式,例如识别玩家拿起或放下的物品、查找脚本区域内的对象等。我们将通过GUID来识别这些对象。 GUID是一个唯一标识符,TS中每个生成的物品都会拥有。即使是两个相同的物品,它们的GUID也各不相同。要查找某个物体的GUID,右键点击该物体并进入“脚本”选项。若在此处点击其GUID,它会复制到剪贴板。GUID始终是字符串,所以要记住字符串需用引号括起来。让我们用物体的GUID创建一些变量。注意:你的GUID会与我的不同。 object1_GUID = '195868' object2_GUID = '333365' checker_GUID = '7dc60d' 定义物体 然后,使用onload函数确保脚本加载时执行以下操作,我们将创建代表这些物体的变量。所有这些变量名必须以小写字母开头且不含空格,除此之外,你可以自由命名变量,但最好能清晰表达其代表的含义。我将使用object1、object2和checker来代表我的对象。我们将使用getObjectFromGUID(string)函数进行识别。我们将GUID放在字符串的位置。 function onload() object1 = getObjectFromGUID(object1_GUID) object2 = getObjectFromGUID(object2_GUID) checker = getObjectFromGUID(checker_GUID) end 操作对象现在我们需要以某种方式操作这些对象。我们将给它们命名。在onload()中,定义好对象后,我们将使用setName(string)函数。注意,setName与其他对象函数一样,必须绑定到某个对象。否则脚本将无法理解我们想要更改哪个对象的名称。setName中的字符串将是我们设置的名称。 object1.setName('Object1') object2.setName('Object2') checker.setName('那个讨厌的检查器') 附加说明:你可能会好奇为什么我们没有将对象GUID直接放入getObject中(例如:object1 = getObjectFromGUID('195868'))。其实我们可以这样做,而且也能正常运行。这个示例是为了告诉你,有时候提前设置一个变量会更方便后续引用。这样一来,如果该变量需要更改(比如新的GUID),你就不必在整个代码中费力查找并修改它了。 如果你愿意,对于检查器,完全可以这样写: function onload() getObjectFromGUID('7dc60d').setName('那个讨厌的检查器') end 我不鼓励初学者这样做,部分原因是代码美观性,另一部分则是为了代码的清晰度。你希望其他人能轻松理解你的代码,而一旦你开始进行比修改对象名称更复杂的操作,就很难弄清楚到底发生了什么。这也会让未来修改代码变成一件麻烦事。 4) 按钮

虽然激活功能的方式有很多,但按钮是一种方便玩家自主激活特定代码段的方式。所有按钮都必须附加到某个对象上,并通过参数来创建。我们希望将按钮附加到“检查器”对象上,这些参数可以在知识库的“对象”页面中找到。其中许多参数是可选的,以下为参考: click_function = 字符串 -- 按钮按下时将激活的函数名称。 function_owner = 对象 -- 确定按钮所激活的函数所在位置(全局或某个对象的脚本)。 labels = 字符串 -- 按钮上显示的名称。 position = 表格 -- 按钮相对于其附加对象中心的 X、Y、Z 坐标。rotation = 表格 --俯仰角、横滚角和偏航角(以度为单位),相对于其所附着的对象。 width = 数字 --按钮的宽度,相对于其对象的缩放比例。 height = 数字 --按钮的高度,相对于其对象的缩放比例。 font_size = 数字 --按钮上文本的大小,相对于其对象的缩放比例。 表格 Lua 中的表格是条目集合。你可以在表格中存储几乎任何内容,并在之后引用它。所有表格都由花括号 {} 表示。你可以通过名称或索引号(即条目编号,Lua 中索引从 1 开始)来引用表格中的条目。我们将在定义 GUID 的位置正下方创建一个表格,然后用条目填充它,以用于 createButton(table) 函数。我们为表格选择的名称是button_paramiters button_parameters = {} button_parameters.click_function = 'buttonClicked' button_parameters.function_owner = nil button_parameters.label = '按我' button_parameters.position = {0,0.8,0} button_parameters.rotation = {0,0,0} button_parameters.width = 500 button_parameters.height = 500 button_parameters.font_size = 100 现在我们有一个包含上述参数的表格。接下来,我们使用对象函数在棋子上创建一个按钮。将以下内容输入到function onload()函数内部,放在其结束之前。 checker.createButton(button_parameters) 检查你的工作:保存并应用代码。现在,你应该能看到一个在棋子上方几英寸处悬浮的按钮。如果你没有看到它,并且没有出现错误,请尝试将棋子翻转过来。它可能是颠倒的,所以按钮藏在桌子里面!如果你确实把棋子翻了过来,记得用棋子正确放置的状态覆盖旧存档。 添加按钮功能现在我们需要在代码中添加按钮功能。为了测试该功能,我们会打印一条消息。我们将把这个用户自定义函数添加到脚本的末尾。 function buttonClicked() print('学习挺有趣的。算是吧。') end 上传脚本后,按下按钮应该会在每次点击时打印一次我们的消息。
当然,你会不停地点击它。

附加说明:创建表格时,有多种实现方法[www.lua.org]。此处采用的方式是为了提供视觉清晰度。然而,像这样创建按钮参数,如果要设置多个按钮,会占用大量空间。我更倾向于以节省空间但又不会导致代码行过长超出屏幕右侧的方式来创建表格。以我们的示例来说,我会这样创建参数表格: button_parameters = { click_function='buttonClicked', function_owner=nil, label='Press Me', position={0,0.8,0}, rotation={0,0,0}, width=500, height=500, font_size=100 } 附加说明:这是开始尝试对对象进行各种操作的绝佳时机。前往知识库中的“物体”页面并尝试操作。移动物体、调换它们的位置、改变颜色,任何你能想到的操作都可以尝试。 额外提示:此外,每当你按下按钮时,其点击函数会触发并带有两个参数。第一个是物体引用,具体是按钮所附着的物体的引用。第二个是按下按钮的玩家的颜色(例如“Blue”),格式为字符串。 5) 逻辑语句

逻辑语句[www.lua.org]通常被称为“条件语句”。它们用于告诉代码在特定情况下要执行的操作。当语句被激活时(例如通过按下按钮),只有在给定条件为真时,语句中包含的逻辑才会被激活。其格式始终为: if 条件 then --当条件为真时激活 end 你还可以添加“else”,这样如果条件为假,就会执行其他操作。注意这里我使用连续的两个减号添加了注释。引擎会忽略--之后同一行的所有内容。如果满足条件(CONDITION),则 --当条件为真时激活 否则 --当条件为假时激活 结束 在这些示例中,我标记为“条件(CONDITION)”的部分被称为关系运算符和条件运算符。[www.tutorialspoint.com] 使用它们,你可以将许多事物相互比较。它们会产生所谓的布尔值(一种要么为“真(true)”要么为“假(false)”的变量值)。 我们的第一个逻辑语句 我们将尝试其中的几个。删除buttonClicked()函数中当前的内容。现在在该函数中输入以下语句: 如果 5 > 6,则 打印("5大于6") 结束 如果 6 > 4,则 打印('6大于5') 结束 如果 5 == 0,则 打印("5等于0?!"else print("不,5不等于0。") end 当使用这些代码行并按下按钮时,你会发现只有位于TRUE语句中的打印函数被执行了。此外,由于5==0是一个假语句,它激活了逻辑中"else"部分的打印函数。

比较变量 再次清除buttonClicked()函数内的所有脚本内容。我们将创建一个新变量,然后对其进行修改。这个新变量将是一个布尔值(bool)。布尔值只能为true(真)、false(假)或nil(nil表示两者都不是)。布尔值始终用全小写字母书写。首先,我们在已定义的对象和检查器GUID下方创建变量: trueOrFalse = true 然后,在buttonClicked函数中,我们将设置一些逻辑来检查trueOrFalse的值是true还是false。如果它为true,我们将打印它为true并将其切换为false。如果再次点击按钮,它将打印为false并切换为true。 if trueOrFalse then print('trueOrFalse的值为true。') trueOrFalse = false else print('trueOrFalse 为 false。') trueOrFalse = true end 我们也可以将其写成“if trueOrFalse == true then”,但这是不必要的。记住,IF 语句只需要传入 True 或 False。由于 trueOrFalse 本身就是其中之一,所以我们可以省略运算符。 6) 循环

循环是只需激活一次就能多次/持续运行的代码段。这些是你在LUA中会用到的一些较复杂元素。它们通常与表格配合使用,让你可以对表格中的每个条目运行代码。 数值for循环 数值for循环[www.lua.org]是一种运行固定次数的循环。你需要给它2个或3个数字以及一个唯一的变量名(我会使用代表索引的“i”),它会从第一个数字开始,一直运行到第二个数字。如果使用第三个数字,它会按该数字递增。所以通常它从1开始每次递增1,但如果你将第三个数字设为2,它就会每次递增2。每个数字用逗号分隔。将你的buttonClicked函数中的代码替换为这个并尝试一下。“i”作为索引,在首次运行时等于1,然后每次递增1,等于2时再次运行,如此循环直到达到10。 for i=1, 10 do print(i) end print('Loop Finished') 按下按钮后的输出结果为:

通用 for 循环 通用 for 循环[www.lua.org]是一种遍历表中条目的循环。例如,我们创建的 button_parameter 表。我们会在循环中设置两个变量,一个用于索引,一个用于值,然后它会遍历所提供表中的每个条目。对于表中的每个条目,它会使索引等于变量名(例如:position、width 等),值等于我们为每个条目赋予的值。在 buttonClicked 中当前的 for 循环之后添加以下内容。 for i, v in pairs(button_parameters) do print(i) end 按下按钮时的输出为:

另一种类型是ipairs。pairs用于处理带有非数字键的表,而ipairs用于处理连续数字键的表(数组)。ipairs会按顺序遍历,而pairs的遍历顺序则不固定。 Break[www.lua.org]会在被激活时立即结束for循环。例如,如果你在数字for循环的打印函数之后添加一行“if i==3 then break end”,那么循环在打印1、2、3之后就会结束。 7)全局外脚本编写 要直接在对象中编写脚本,在游戏中右键点击该对象,进入“脚本”选项,然后选择“Lua编辑器”(如果你使用Atom,这会在Atom中打开一个窗口)。 在这里编写LUA脚本时,其用法与全局脚本类似。除非你需要引用脚本所属的对象,否则只需直接写“self”(无需引号,全小写)。例如,要在自身创建一个按钮,你可以使用self.createButton(参数表)。 结语 希望这篇Lua入门介绍能帮助你更好地理解脚本的一些底层机制。如果没有,那我希望你在来喷我的路上迷路。 记住,知识库包含《桌面模拟器》中所有函数的相关信息。掌握这些知识,再加上对if/else/then和for循环的一些基本练习,你几乎可以完成任何想做的事情。祝你好运。 另有一篇指南已创建,如果你想学习更多内容,可以查看《学习更多Lua》。它附带了许多脚本示例供你试用,我希望这些示例能教会你一些良好的编码实践。另外,如果你正在学习编程,我已经整理了一份 Lua 函数列表,用于处理一些更复杂的流程,你可以在这里找到它。
2026-02-12 09:01:13 发布在
Tabletop Simulator
说点好听的...
收藏
0
0
