已创建地图后,我们可以开始构建脚本了。剩下的这个课程将重点关注脚本所有不同的元素。
设置脚本
战斗模式将使用模块脚本和普通脚本的组合。以下是脚本和其函数。
游戏管理器 | 脚本。 使用游戏设置中的变量从匹配管理器运行函数 |
匹配管理器 | 模块脚本。 运行如发送玩家进入竞技场或跟踪时间在匹配赛中。 |
游戏设置 | 模块脚本。用于其他脚本的常见变量。 |
游戏设置脚本
创建名为 GameSettings 的模块脚本,用于储存其他脚本中使用的变量,例如匹配和中场休息时间。这些变量将被游戏管理器脚本稍后使用。
在 ServerStorage 中,创建一个名为ModuleScripts的文件夹。在该文件夹中,创建一个名为GameSettings的新模块脚本。
打开游戏设置并将模块表重命名为与脚本名称匹配。
local GameSettings = {}return GameSettings在模块表中,为以下用途添加变量。 为每个值做出最佳猜想,您总是可以在测试时更改它。
- 中场休息时间 - 秒后玩家才能开始匹配。
- 比赛时长 - 以秒为单位的比赛时长。
- 最低参赛者 - 最小参赛者数量需要开始。
- 过渡时间 - 在秒后进行匹配之前和之后的时间。使游戏循环的零件之间的过渡更顺滑。
local GameSettings = {}-- 游戏变量GameSettings.intermissionDuration = 5GameSettings.matchDuration = 10GameSettings.minimumPlayers = 2GameSettings.transitionTime = 5return GameSettings
MatchManager 脚本
GameManager 的第二个脚本是 MatchManager 。 此脚本管理任务,例如启动计时器或重置玩家一旦结束比赛。
在 MatchManager 中,有一个名为 prepareGame() 的函数,可以通过将玩家转换为匹配赛开始游戏。
在 ServerStorage > ModuleScripts > 添加一个名为 MatchManager 的模块脚本。重命名模块表。
local MatchManager = {}return MatchManager增加一个名为 prepareGame() 的新模块功能。包括打印声明来测试脚本。
local MatchManager = {}function MatchManager.prepareGame()print("Game starting!")endreturn MatchManager
编写游戏循环
主游戏循环将使用创建的变量在GameManager脚本中编码。记住,游戏循环有三个阶段:中场休息、比赛和清理和重置。
游戏管理器脚本
这是一个普通的服务器脚本,请将其放入 ServerScriptService 而不是模块脚本目录。 实际游戏循环将在一段时间内真的循环。
在 ServerScriptService 中,创建一个名为 GameManager 的新脚本。
为“ServerStorage”服务添加变量,这是“ModuleScripts”的所在地。然后为“Players”服务添加变量,这将在中场休息时检查玩家数量。
-- 服务local ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")要使用以前创建的模块:
- 将 moduleScripts 设置到 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 true do 循环中,输入 repeat ,并按 输入 键完成自动完成,并使用关键字 1> til1> 。
while true dorepeatuntilend检查当前玩家数量 (#Players:GetPlayers()) 是否大于或等于在 GameSettings 模块中创建的 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 。如果小于 1 ,脚本可能会重复太频繁,导致滞后问题。
结束中场休息
一旦有足够的玩家,请等待他们短暂的过渡时间。然后,通过调用 prepareGame() 函数在 MatchManager 中发送他们到比赛。记住,该函数只打印一行,但您稍后会添加更多代码。
在重复循环结束时,添加一个打印声明,说明中场休息结束,测试你的代验证码。然后,使用 GameSettings 的 transitionTime 变量使用。
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() ,它需要退出重复循环。但要实现这一点,需要有更多 than 一个玩家。 这意味着 如果您使用“玩测试”按钮,函数将永远不会运行,因为您是游戏中的唯一玩家(除非您的最低玩家是一个)。 要测试这一点,您需要模拟多人游戏。
启动一个本地服务器
要测试需要超过一名玩家的代码,请创建一个本地服务器。 与发布的游戏通常在 Roblox 服务器上,但 本地服务器 模拟您的电脑上的多人游戏。
要启动一个本地服务器,请在 测试 选项卡> 客户端和服务器 部分>将玩家下拉列为游戏设置的最低游戏玩家数。 此课程使用 2 个玩家。
单击“开始”以启动服务器。
等待服务器设置。多个窗口将在您的原始 Studio 窗口之上打开。您可能需要允许 Roblox Studio 从 firewalls 或其他在线安全软件中访问。
排查提示
在此时,您无法查看测试服务器,请尝试以下其中一个。
- 如果您有服务器启动时的任何问题,请重新检查文章服务器和路由器问题。
- 将玩家数量设置为小数,例如 2 或 3。
- 如果问题仍然没有解决,请尝试重新启动 Studio 或重新启动您的计算机。
在本地服务器上测试
当服务器启动时,您会看到多个窗口。每个窗口都代表服务器/客户端关系的不同部分。
- 服务器 (绿色边框) 运行游戏。
- 客户端 (蓝色边框) 模拟玩家的体验。
当服务器运行时,您可以检查代码是否工作。
找到 服务器 窗口,边框绿色。检查从MatchManager脚本调用的打印声明。因为有重复循环,您会看到相同的打印声明重复。
一旦您完成测试,在任何窗口中关闭服务器按钮。这将关闭所有服务器和客户端窗口,并将您带回到您的普通 Studio 窗口。
排查提示
如果没有出现预期的打印声明,请尝试以下其中一个。
- 检查函数 like prepareGame() 是否在真实时间内循环。
- 如果 MatchManager 打印失败,请检查一些常见的问题,例如确保 MatchManager 脚本在 GameManager 中是否需要,或将 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
MatchManager 脚本
local MatchManager = {}
function MatchManager.prepareGame()
print("Game starting!")
end
return MatchManager
游戏设置脚本
local GameSettings = {}-- 游戏变量GameSettings.intermissionDuration = 5GameSettings.roundDuration = 10GameSettings.minimumPlayers = 2GameSettings.transitionTime = 5return GameSettings