編寫遊戲循環

*此內容是使用 AI(Beta 測試版)翻譯,可能含有錯誤。若要以英文檢視此頁面,請按一下這裡

創建地圖後,是時候開始建立腳本了。本課程的剩餘部分將主要專注於撰寫遊戲循環的各種元素。

設定腳本

戰鬥皇室將使用模組腳本和普通腳本的組合。以下是腳本和其功能。

遊戲經理腳本。使用遊戲設定中的變量從匹配管理器運行功能
匹配管理器模組腳本。執行功能,例如將玩家送入競技場或記錄相符賽時間。
游戲設定模組腳本。儲存常用變數,由其他腳本使用。

GameSettings 腳指令碼

創建名為 GameSettings 的模組腳本來儲存其他腳本使用的變量,例如比賽和中場休息時間。這些變量將在稍後由遊戲管理員指令碼使用。

  1. 伺服器儲存 中,創建一個名為 ModuleScripts 的文件夾。在該文件夾中,創建一個新的模組腳本名為 GameSettings 的模組腳本。

  2. 開啟「遊戲設定」並將模組表重新命名,以符合腳指令碼名稱。


    local GameSettings = {}
    return GameSettings
  3. 在模組表中,添加變數以用於以下用途。為每個值提供最佳猜測,您可以在測試時隨時更改。

    • 中場休息時間 - 玩家在相符賽前等待的秒數。
    • 匹配時間 - 匹配的時間(秒)。
    • 最少玩家 - 需要啟動的最小玩家數量。
    • 轉換時間 - 秒內比賽前和比賽後的時間。使遊戲循環的部分之間的轉換變得更平緩。

    local GameSettings = {}
    -- 游戲變量
    GameSettings.intermissionDuration = 5
    GameSettings.matchDuration = 10
    GameSettings.minimumPlayers = 2
    GameSettings.transitionTime = 5
    return GameSettings

匹配管理員腳指令碼

連接到遊戲管理器的第二個腳本是匹配管理器。這個腳本管理任務,例如開始計時器或重置玩家一旦比賽結束。

在 MatchManager 內的一個名為 prepareGame() 的功能開始遊戲,通過將玩家轉移到比相符中來啟動遊戲。

  1. 在伺服器儲存 > 模組腳本 > 添加一個名為 MatchManager 的模組腳本。重命名模組表。


    local MatchManager = {}
    return MatchManager
  2. 新增名為 prepareGame() 的 MatchManager 新模組功能。包括印出聲明以後測試腳本。


    local MatchManager = {}
    function MatchManager.prepareGame()
    print("Game starting!")
    end
    return MatchManager

編寫遊戲循環

主遊戲循環將使用剛剛創建的變量在遊戲管理員腳本中編寫。記住,遊戲循環中有三個階段:中場休息、競賽和清理和重置。

遊戲管理員指令碼

這個腳本是一個普通的伺服器指令碼,因此將它放置在伺服器腳本服務中,而不是模組腳本夾中。實際遊戲循環將在 while true 循環中。

  1. 在 ServerScriptService 中,創建一個名為 GameManager 的新腳本。

  2. 添加服務「伺服器儲存」的變數,這是模組腳本存在的地方。然後添加一個變量「玩家」,用於檢查中場休息期間玩家數量。


    -- 服務
    local ServerStorage = game:GetService("ServerStorage")
    local Players = game:GetService("Players")
  3. 要使用先前創建的模組:

    • 將變量 moduleScripts 命名為模組指令碼資料夾的位置。
    • 添加名為 matchManagergameSettings 的變量。將每個變量設為需要對應的指令碼。

    -- 服務
    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"))
  4. 在變量之後,添加 while true do 循環。遊戲循環的所有階段都會進入重複無限期。


    -- 模組腳本
    local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
    local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
    local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
    -- 主遊戲循環
    while true do
    end

編寫中場休息

遊戲迴圈無限期運行時,中場休息應暫停迴圈並僅在有足夠的玩家時繼續。要碼寫此暫停,請在 while 循環中包含一個嵌套重複循環以實現中場休息。這個巢穴循環將重複直到有足夠的玩家,暫停主循環。一旦有足夠的玩家,它就會退出並將玩家轉換為比相符。

使用 重複循環 ,循環中的代碼至少會運行一次。與 while 循環不同,它不會在循環結束前檢查其條件。這樣可以確保玩家總是在比相符開始前去到大廳。

  1. while true do 循環中,輸入 repeat 並按下 Enter 以使用關鍵字 until 來自動完成。


    while true do
    repeat
    until
    end
  2. 檢查目前玩家數量 (#Players:GetPlayers()) 是否大於或等於在遊戲設置模組中創建的 minimumPlayers 變量。


    while true do
    repeat
    until #Players:GetPlayers() >= gameSettings.minimumPlayers
    end
  3. 在重複循環中,添加一個印出聲明說中場休息開始了。使用 task.wait() 從遊戲設定中暫停使用 intermissionDuration 來暫停中場休息。


    while true do
    repeat
    print("Starting intermission")
    task.wait(gameSettings.intermissionDuration)
    until #Players:GetPlayers() >= gameSettings.minimumPlayers
    end
  4. 玩測並檢查是否至少兩次顯示印刷聲明 "Starting intermission"看到訊息兩次證明重複循環沒有找到足夠的玩家並再次運行。您必須等待中場休息的長度才能第二次看到訊息。

排除故障提示

在這個時候,如果你沒有按照預期生成,請嘗試以下方法之一。

  • task.wait() 應該在重複循環內。沒有等待,腳本將在一秒鐘內執行過多次,超載 Roblox Studio 並導致錯誤。
  • 在遊戲設定模組中,變量 intermissionDuration 應大於 1。如果低於,腳本可能會重複太頻繁,導致速度問題。

結束中場休息

一旦有足夠的玩家,讓他們等待短時間的轉換。然後,將它們傳送到匹配中,稱呼匹配管理器中的 prepareGame() 函數。記住,那個功能只會列印一行,但你稍後會添加更多代碼。

  1. 在重複循環結束時,添加一個印出聲明,說明中斷已結束以測試您的代碼。然後,使用 GameSetting 的 變量跟隨它。


    while true do
    repeat
    print("Starting intermission")
    task.wait(gameSettings.intermissionDuration)
    until #Players:GetPlayers() >= gameSettings.minimumPlayers
    print("Intermission over")
    task.wait(gameSettings.transitionTime)
    end
  2. 等待後,從匹配管理器模組呼叫 prepareGame()。當代碼運行時,會僅將文字列印到輸出窗口。等到下一個部分測試此代碼。


    while true do
    repeat
    print("Starting intermission")
    task.wait(gameSettings.intermissionDuration)
    until #Players:GetPlayers() >= gameSettings.minimumPlayers
    print("Intermission over")
    task.wait(gameSettings.transitionTime)
    matchManager.prepareGame()
    end

測試多人遊戲

目前,要讓代碼運行 prepareGame(),它需要退出重複循環。但是,要做到這一點,需要有多於一名玩家。這意味著如果您使用播放測試按鈕,功能將永遠不會運行,因為您是遊戲中唯一的玩家(除非您的最低玩家數是一個)。要測試這一點,你需要模擬多人遊戲。

啟動本地伺服器

要測試需要超過一名玩家的代碼,請創建一個本地伺服器。雖然發布的遊戲通常在 Roblox 伺服器上,但 本地伺服器 會模擬在您的電腦上使用模擬玩家的多人遊戲。

  1. 若要啟動本地伺服器,請在 測試 標籤 > 客戶端和伺服器 部分 >設置玩家掛斷到 GameSetting 變量 minimumPlayers 的玩家數量。這個課程使用 2 名玩家。

  2. 按一下「開始」以開始伺服器。

  3. 等待幾秒鐘,讓伺服器設定。多個窗口將在原始 Studio 窗口之外開啟。您可能需要允許從防火牆或其他在線安全軟件中進入 Roblox Studio 。

排除故障提示

在這個時候,您無法看到測試服務器,請嘗試以下任一選項。

  • 如果您有服務器啟動時發生任何問題,請檢查防火牆和路由器問題文章。
  • 將玩家數設為小數量,例如 2 或 3。
  • 如果問題未解決,請嘗試重新啟動 Studio 或重新啟動您的電腦。

在本地伺服器上測試

當伺服器開始時,您會看到多個窗口。每個窗口代表不同的伺服器/客戶關係。

  • 伺服器 (綠色邊框) 執行遊戲。
  • 客戶端 (藍色邊框) 模擬玩家的體驗。

綠色邊緣的伺服器
>

擁有藍色邊緣的客戶端
>

當伺服器運行時,您可以檢查代碼是否運作。

  1. 尋找綠色邊框的 伺服器 窗口。檢查從 MatchManager 腳指令碼中呼叫的列印聲明。因為有一個重複循環,你會看到相同的印字聲明重複。

  2. 一旦您完成測試,在任何窗口中,使用「清除」按鈕關閉伺服器。這將關閉所有服務器和客戶端窗口,並將你帶回到你的正常 Studio 窗口。

排除故障提示

在這個時候,如果預期的列印聲明未出現,請嘗試以下方法之一。

  • 檢查功能如 prepareGame() 是否在 while true 循環的範圍內。
  • 如果從匹配管理器列印失敗,請檢查模組腳本的一些常見問題解決方案,例如確保匹配管理器腳本在遊戲管理器中需要或將 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 do
repeat
print("Starting intermission")
task.wait(gameSettings.intermissionDuration)
until #Players:GetPlayers() >= gameSettings.minimumPlayers
print("Intermission over")
task.wait(gameSettings.transitionTime)
matchManager.prepareGame()
end

匹配管理員腳指令碼


local MatchManager = {}
function MatchManager.prepareGame()
print("Game starting!")
end
return MatchManager

GameSettings 腳指令碼


local GameSettings = {}
-- 游戲變量
GameSettings.intermissionDuration = 5
GameSettings.roundDuration = 10
GameSettings.minimumPlayers = 2
GameSettings.transitionTime = 5
return GameSettings