在回合期間,腳本需要記錄時間並在不同腳本之間傳送信號。時間將使用時間指令碼管理,而事件,是 Roblox 編寫中的一個概念,會偵測到比相符結束等變更。
透過事件傳送信號
現在玩家已經在競技場中,事件可以用來警告比賽開始和計時器代碼開始。之後,事件也可以用來警告比相符結束,以及是時候將玩家轉回大廳了。
這些事件未預製,因此需要創建自訂事件對象,稱為 可綁定事件 ,以便執行。可綁定事件通常用於玩家發起的行動,與事件如 Touched 或 Changed 類似。
多個腳本可以聆聽相同的可綁定事件。這樣可以使您的代碼井然有序,並且使以後為比賽開始或結束添加額外代碼變得更容易。
創建可綁定的事件
從創建可綁定的比相符開始和結束事件對象開始。因為可綁定事件不會與客戶端互動,因此可以儲存在伺服器儲存中。
在伺服器儲存中,創建一個名為「事件」的新文件夾。在該文件夾中,創建兩個 可綁定事件 ,名為「匹配開始」和「匹配結束」。
使用事件
現在,當玩家進入競技場時,中場休息會繼續重新啟動,而不是開始計時器。主遊戲循環需要被告知停止,直到匹配結束事件發生,然後才能移至代碼的下一部分。
事件有兩個內置功能:Connect()和Wait()。取代以前使用 Connect() 的方式,在 MatchEnd 上呼叫 Wait() 來暫停游戲管理員腳本直到 MatchEnd 被發射。在這種情況下,等待功能會暫停代碼,直到遊戲管理員收到信號表示比賽結束。
在 遊戲管理器 中,創建變量為 Events 文件夾和 MatchEnd 事件。
-- 模組腳本local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local matchManager = require(moduleScripts:WaitForChild("MatchManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))-- 事件local events = ServerStorage:WaitForChild("Events")local matchEnd = events:WaitForChild("MatchEnd")讓腳本等待結束事件發射,然後才能繼續移動。在 循環 中,在 結束 時,輸入:matchEnd.Event:Wait()
while true dorepeattask.wait(gameSettings.intermissionDuration)print("Restarting intermission")until #Players:GetPlayers() >= gameSettings.minimumPlayersprint("Intermission over")task.wait(gameSettings.transitionTime)matchManager.prepareGame()-- 等待器位置等待遊戲的長度。matchEnd.Event:Wait()end測試 遊戲。確認一旦玩家進入競技場,中場循環 不會 繼續。腳本現在正在等待 matchEnd 信號發觸發。
排除故障提示
在這個時候,代碼不像預期的那樣運作,請嘗試以下方法之一。
- 在 matchEnd.Event:Wait() 中雙重檢查點或斑點運作器的使用。
- 請確保 MatchEnd 是可綁定的事件,而不是其他輸入,例如遠端事件。
使用定時器
造成比賽結束的一個條件是定時器到期,這將通過腳指令碼處理。
設定計時器
要將定時器添加到遊戲中,請在下列步驟中使用預製模組腳本。它包括啟動和結束計時器的功能,以及返回剩餘時間的數量。
在伺服器儲存 > 模組腳本中,創建一個名為計時器的新模組腳本。
將代碼替換為以下代碼。
local Timer = {}Timer.__index = Timerfunction Timer.new()local self = setmetatable({}, Timer)self._finishedEvent = Instance.new("BindableEvent")self.finished = self._finishedEvent.Eventself._running = falseself._startTime = nilself._duration = nilreturn selfendfunction Timer:start(duration)if not self._running thentask.spawn(function()self._running = trueself._duration = durationself._startTime = tick()while self._running and tick() - self._startTime < duration dotask.wait()endlocal completed = self._runningself._running = falseself._startTime = nilself._duration = nilself._finishedEvent:Fire(completed)end)elsewarn("Warning: timer could not start again as it is already running.")endendfunction Timer:getTimeLeft()if self._running thenlocal now = tick()local timeLeft = self._startTime + self._duration - nowif timeLeft < 0 thentimeLeft = 0endreturn timeLeftelsewarn("Warning: could not get remaining time, timer is not running.")endendfunction Timer:isRunning()return self._runningendfunction Timer:stop()self._running = falseendreturn Timer在 MatchManager 中,需要 GameSettings 和 Timer 模組。
local MatchManager = {}-- 服務local ServerStorage = game:GetService("ServerStorage")-- 模組腳本local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local timer = require(moduleScripts:WaitForChild("Timer"))在變量下方,通過設置名為 myTimer 的變量等於 timer.new() 來創建新的計時器對象。這個對象將用於呼叫開始和停止計時器的函數。
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local timer = require(moduleScripts:WaitForChild("Timer"))-- 創建一個新的計時器對象,用於跟蹤比賽時間。local myTimer = timer.new()
開始和停止
現在創建了定時器,在比相符期間使用包含的功能 start() 和 stop() 。以下是每個功能的說明和它接受的參數。
- start(time) - 啟動計時器,使用秒為參數的時間。
- finished:Connect(functionName) - 當定時器結束時,運行傳遞為參數的函數。
在 配對管理器 中,創建一個新函數名為 timeUp() 的新功能,以便在計時器結束時運行。包括測試列印聲明。
local myTimer = timer.new()-- 本地功能local function timeUp()print("Time is up!")end-- 模組功能function MatchManager.prepareGame()playerManager.sendPlayersToMatch()endreturn MatchManager在 timeUp() 下方,添加一個名為 startTimer() 的功能,並使用打印聲明顯示時間。您稍後將在遊戲中顯示計時器。
-- 本地功能local function timeUp()print("Time is up!")endlocal function startTimer()print("Timer started")end要啟動和停止計時器,在 startTimer() :
- 呼叫 myTimer.start() . 傳遞 gameSettings.matchDuration .
- 呼叫 myTimer.finished:Connect() . 傳遞 timeUp() .
-- 本地功能local function startTimer()print("Timer started")myTimer:start(gameSettings.matchDuration)myTimer.finished:Connect(timeUp)end
啟動計時器
定時器可以使用匹配開始事件在比賽開始時啟動。
在 MatchManager 中,在模組變量下,創建變量來儲存事件文件夾、比賽開始和比賽結束(將在未來的課程中使用)。
-- 模組腳本local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local timer = require(moduleScripts:WaitForChild("Timer"))-- 事件local events = ServerStorage:WaitForChild("Events")local matchStart = events:WaitForChild("MatchStart")local matchEnd = events:WaitForChild("MatchEnd")--創建計時器local myTimer = timer.new()上面的 return MatchManager , 連接匹配開始事件到 startTimer() .
-- 模組功能function MatchManager.prepareGame()playerManager.sendPlayersToMatch()endmatchStart.Event:Connect(startTimer)return MatchManager要發射比賽開始事件,在 prepareGame() ,輸入 matchStart:Fire() .
-- 模組功能function MatchManager.prepareGame()playerManager.sendPlayersToMatch()matchStart:Fire()end測試遊戲。在輸出窗口中,確認您可以看到計時器啟動和停止功能的印刷聲明。
已完成的腳本
以下是完成的腳本來檢查您的工作。
匹配管理員腳指令碼
local MatchManager = {}
-- 服務
local ServerStorage = game:GetService("ServerStorage")
-- 模組腳本
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local timer = require(moduleScripts:WaitForChild("Timer"))
-- 事件
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- 創建一個新的計時器對象,用於跟蹤比賽時間。
local myTimer = timer.new()
-- 本地功能
local function timeUp()
print("Time is up!")
end
local function startTimer()
print("Timer started")
myTimer:start(gameSettings.matchDuration)
myTimer.finished:Connect(timeUp)
end
-- 模組功能
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
matchStart.Event:Connect(startTimer)
return MatchManager
遊戲管理員指令碼
-- 服務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"))-- 事件local events = ServerStorage:WaitForChild("Events")local matchEnd = events:WaitForChild("MatchEnd")while true dorepeattask.wait(gameSettings.intermissionDuration)print("Restarting intermission")until #Players:GetPlayers() >= gameSettings.minimumPlayersprint("Intermission over")task.wait(gameSettings.transitionTime)matchManager.prepareGame()-- 等待器位置等待遊戲的長度。matchEnd.Event:Wait()end