创建了地图后,是时候开始构建脚本了。本课程剩余部分将重点关注编写游戏循环的所有不同元素的脚本。
设置脚本
战斗皇家将使用模块脚本和普通脚本的组合。以下是脚本和其功能。
游戏管理器 | 脚本。使用游戏设置中的变量从匹配管理器运行函数 |
匹配管理器 | 模块脚本。运行功能,例如将玩家送入竞技场或跟踪匹配赛中的时间。 |
游戏设置 | 模块脚本。存储常用变量,由其他脚本使用。 |
游戏设置脚本
创建一个名为 GameSettings 的模块脚本来存储其他脚本使用的变量,例如比赛和中场休息时间。这些变量将在稍后由游戏管理器脚本使用。
在 服务器存储 中,创建一个名为 ModuleScripts 的文件夹。在那个文件夹中,创建一个名为 GameSettings 的新模块脚本。
打开游戏设置并将模块表重命名为与脚本名称匹配的名称。
local GameSettings = {}return GameSettings在模块表中,添加变量以进行以下使用。对每个值进行最佳猜测,您随时都可以在测试时更改它。
- 中场休息时间 - 秒玩家在匹配赛前等待。
- 匹配时长 - 匹配的时长(秒)。
- 最小玩家 - 需要启开始的最小数量玩家。
- 过渡时间 - 秒内的比赛前后时间。使游戏循环的部分之间的过渡变得更平缓。
local GameSettings = {}-- 游戏变量GameSettings.intermissionDuration = 5GameSettings.matchDuration = 10GameSettings.minimumPlayers = 2GameSettings.transitionTime = 5return GameSettings
匹配管理器脚本
连接到 GameManager 的第二个脚本是 MatchManager 。该脚本管理任务,例如启动计时器或在比赛结束后重置玩家。
在 MatchManager 中,一个名为 prepareGame() 的函数开始游戏,通过将玩家转换为比匹配来实现。
在服务器存储 > 模块脚本 > 添加一个名为 MatchManager 的模块脚本。重命名模块表。
local MatchManager = {}return MatchManager将新模块函数添加到 MatchManager 名为 prepareGame() 的模块中。包含打印声明以在稍后测试脚本。
local MatchManager = {}function MatchManager.prepareGame()print("Game starting!")endreturn MatchManager
编写游戏循环
主游戏循环将使用刚刚创建的变量在游戏管理器脚本中编写。请记住,游戏循环中有三个阶段:中场休息、竞赛和清理和重置。
游戏管理器脚本
该脚本是普通的服务器脚本,因此将其放置在 ServerScriptService 中,而不是模块脚本文件夹中。实际游戏循环将在 while true do 循环中。
在 ServerScriptService 中,创建一个名为 GameManager 的新脚本。
为服务“ServerStorage”添加变量,这是模块脚本存在的地方。然后为服务“玩家”添加变量,该变量将在中场休息期间检查玩家数量所需。
-- 服务local ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")要使用之前创建的模块:
- 将变量名为 moduleScripts 的变量设置到模块脚本文件夹的位置。
- 添加名为 matchManager 和 gameSettings 的变量。将每个变量设置为需要其各自的脚本。
-- 服务local ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- 模块脚本local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local matchManager = require(moduleScripts:WaitForChild("MatchManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))在变量之后,添加一个 while true do 循环。游戏循环的所有阶段都会进入重复无限期。
-- 模块脚本local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local matchManager = require(moduleScripts:WaitForChild("MatchManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))-- 主游戏循环while true doend
编写中场休息
虽然游戏循环无限循环,但中场休息应暂停循环,只有当比匹配有足够的玩家时才继续。要编写这个暂停,包括在 while 循环中的嵌套重复循环以及中场休息。这个嵌套循环将继续重复,直到有足够的玩家,暂停主循环。一旦有足够的玩家,它就会退出并将玩家转换为比匹配。
使用 重复循环 ,循环中的代码至少会运行一次。与 while 循环不同,它不会在循环结束之前检查条件。这保证玩家始终在比匹配前去大厅。
在 while true do 循环中,输入 repeat 并按 Enter 以自动完成关键字 until 。
while true dorepeatuntilend检查当前玩家数量 (#Players:GetPlayers()) 是否大于或等于游戏设置模块中先前创建的 minimumPlayers 变量。
while true dorepeatuntil #Players:GetPlayers() >= gameSettings.minimumPlayersend在重复循环中,添加一个打印声明,说明中场休息正在开始。使用 task.wait() 从游戏设置中暂停使用 intermissionDuration 来进行中场休息。
while true dorepeatprint("Starting intermission")task.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersend播放测试,检查打印声明 "Starting intermission" 至少显示两次。看到消息两次证明重复循环没有找到足够的玩家并再次运行。你必须等待一段中场休息时间才能第二次看到消息。
排除问题的提示
在这一点上,如果你没有按预期生成,请尝试以下方法之一。
- task.wait() 应该在重复循环内。没有等待,脚本在一秒内运行太多次,会超载 Roblox Studio 并导致错误。
- 在游戏设置模块中,变量 intermissionDuration 应大于 1。如果低于,脚本可能会重复太频繁,导致速度问题。
结束中场休息
一旦有足够的玩家,让他们等待短暂的过渡时间。然后,通过在匹配管理器中调用 prepareGame() 函数将它们发送到匹配中请记住,这个函数只打印一行,但你稍后会添加更多代码。
在重复循环结束时,添加一个打印声明,说中断已结束以测试您的代验证码。然后,使用游戏设置的 变量跟随它。
while true dorepeatprint("Starting intermission")task.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersprint("Intermission over")task.wait(gameSettings.transitionTime)end等待后,从匹配管理器模块中调用 prepareGame()。当代码运行时,这将只打印文本到输出窗口。等到下一节测试这段验证码。
while true dorepeatprint("Starting intermission")task.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersprint("Intermission over")task.wait(gameSettings.transitionTime)matchManager.prepareGame()end
测试多人游戏
现在,要使代码运行 prepareGame() ,它需要退出重复循环。但是,要做到这一点,需要至少有一个玩家。这意味着如果你使用播放测试按钮,函数永远不会运行,因为你是游戏中唯一的玩家(除非你的最低玩家数是一个)。要测试这一点,你需要模拟多人游戏。
启动本地服务器
要测试需要多个玩家的代码,创建一个本地服务器。虽然发布的游戏通常在 Roblox 服务器上,但 本地服务器 可以模拟在您的计算机上使用模拟玩家的多人游戏。
要启动本地服务器,请在 测试 选项卡 > 客户端和服务器 部分 >将玩家下拉列表设置为游戏设置变量 minimumPlayers 的玩家数量。这一课程使用 2 名玩家。
单击启动开始启动服务器。
等待服务器设置几秒钟。除了您的原始 Studio 窗口外,将打开多个窗口。您可能需要允许从防火墙或其他在线安全软件中访问 Roblox Studio。
排除问题的提示
在这一点上,您无法看到测试服务器,请尝试以下其中一个。
- 如果您有服务器启动时的任何问题,请检查防火墙和路由器问题文章。
- 将玩家数设置为小数量,例如 2 或 3
- 如果问题没有解决,请尝试重新启动 Studio 或重新启动您的计算机。
在本地服务器上进行测试
当服务器启动时,你会看到多个窗口。每个窗口都代表服务器/客户端关系的不同部分。
- 服务器 (绿色边框) 运行游戏。
- 客户端 (蓝色边框)模拟玩家的体验。


当服务器运行时,您可以检查代码是否工作。
找到具有绿色边框的 服务器 窗口。检查从匹配管理器脚本中调用的打印声明。因为存在重复循环,你会看到相同的打印声明重复。
一旦您完成测试,在任何窗口中,通过清理按钮关闭服务器。这将关闭所有服务器和客户端窗口,并将你带回到你的正常 Studio 窗口。
排除问题的提示
在这一点上,如果预期的打印声明未出现,请尝试以下方法之一。
- 检查功能如 prepareGame() 是否属于 while 真实循环的范围。
- 如果从匹配管理器打印没有工作,请检查一些常见的排除问题方法,例如确保匹配管理器脚本在游戏管理器中需要或添加 prepareGame() 到该模块的表中。
已完成的脚本
以下是完成的脚本来检查您的工作。
游戏管理器脚本
-- 服务local ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- 模块脚本local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local matchManager = require(moduleScripts:WaitForChild("MatchManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))-- 主游戏循环while true dorepeatprint("Starting intermission")task.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersprint("Intermission over")task.wait(gameSettings.transitionTime)matchManager.prepareGame()end
匹配管理器脚本
local MatchManager = {}
function MatchManager.prepareGame()
print("Game starting!")
end
return MatchManager
游戏设置脚本
local GameSettings = {}-- 游戏变量GameSettings.intermissionDuration = 5GameSettings.roundDuration = 10GameSettings.minimumPlayers = 2GameSettings.transitionTime = 5return GameSettings