ゲームの最後のフェーズをコードする時間です:起動とリセット。このフェーズのコードは、ゲームが休憩を開始し、各プレイヤーに対して同じようにマッチを開始することを確認します。
GUI の更新
前に、清掃とリセットを実行する前に、プレイヤーにゲームが DisplayManager を使用して適切なステータスを表示するようにしてください。
勝者の名前を取得する
勝利したプレイヤーの名前を取得するか、それがある場合は、コードはそのサイズを 1 に減少しているかどうかをチェックします。以前は、コードは、アクティブプレイヤーの表のサイズが 1 に減少しているかどうかをチェックしました。残りのプレイヤーの名前を取得するには、そのテーブルの最初のインデックスに戻ります。
PlayerManager で、getWinnerName() という名前の新しいモジュール機能を開始します。
function PlayerManager.getWinnerName()end-- イベントPlayers.PlayerAdded:Connect(onPlayerJoin)activePlayers[1] に存在するものがある場合、 if 文は実行されます。ただし、テーブル数が以前にチェックされていたため、プレイヤーは接続を切断したか、ゲームを終了した可能性があります。
function PlayerManager.getWinnerName()local winningPlayer = activePlayers[1]if winningPlayer thenendend以下の if 文で:
- プレイヤーの名前を返します。
- そうでない場合は、エラーストリングを返します。
function PlayerManager.getWinnerName()local winningPlayer = activePlayers[1]if winningPlayer thenreturn winningPlayer.Nameelsereturn "Error: No winning player found"endend
最終ステータスを取得する
モジュール機能を使用して、タイマーが終了するか、1人のプレイヤーが終了するかから情報を取得します。次に、その状態変数を DisplayManager に送信し、ステータス GUI を適切なメッセージで更新します。
In MatchManager で、 getEndStatus() という名前の新しいモジュール関数をコードし、 endState パラメータでメッセージを保存します。メッセージを送信するために、空の変数を名前付けて 1> statusToReturn1> を追加します。
function MatchManager.prepareGame()playerManager.sendPlayersToMatch()matchStart:Fire()endfunction MatchManager.getEndStatus(endState)local statusToReturnendmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerif および else 文を使用して statusToReturn の値を設定します。終了状態変数をチェックします: FoundWinner および TimerUp。エラーチェックのために、終了に別を含めます: 1>1> および 4>4> 。
function MatchManager.getEndStatus(endState)local statusToReturnif endState == gameSettings.endStates.FoundWinner thenelseif endState == gameSettings.endStates.TimerUp thenelseendend各コンディションについて次のを追加してください:
FoundWinner
- playerManager.getWinnerName() を使用して勝者の変数。
- 勝者を発表するストリングを含む statusToReturn を更新します。
TimerUp
- 更新 statusToReturn をストリングで時間切れを宣言します。
Else
- エラーメッセージがある場合は、statusToReturn を更新します。
function MatchManager.getEndStatus(endState)local statusToReturnif endState == gameSettings.endStates.FoundWinner thenlocal winnerName = playerManager.getWinnerName()statusToReturn = "Winner is : " .. winnerNameelseif endState == gameSettings.endStates.TimerUp thenstatusToReturn = "Time ran out!"elsestatusToReturn = "Error found"endendreturn statusToReturn を入力してメッセージを返信します。
function MatchManager.getEndStatus(endState)local statusToReturnif endState == gameSettings.endStates.FoundWinner thenlocal winnerName = playerManager.getWinnerName()statusToReturn = "Winner is : " .. winnerNameelseif endState == gameSettings.endStates.TimerUp thenstatusToReturn = "Time ran out!"elsestatusToReturn = "Error found"endreturn statusToReturnend
表示とテスト
GameManager で更新されたお知らせを取得し、DisplayManager を使用してプレイヤーに表示します。
Open GameManager を開きます。 while true do loop, delete last print statement. その後、endStatus という名前の変数を作成します。 set it equal to calling matchManager.getEndStatus(endState) 。
while true dodisplayManager.updateStatus("Waiting for Players")repeattask.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersdisplayManager.updateStatus("Get ready!")task.wait(gameSettings.transitionTime)matchManager.prepareGame()local endState = matchEnd.Event:Wait()local endStatus = matchManager.getEndStatus(endState)endGUI レーベルに表示される返されたメッセージを表示するには、displayManager.updateStatus() を呼び出し、endStatus をパスします。
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)ゲームを暫停させて、プレイヤーがメッセージを見るために、transitionTime を使用して待ちます。
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)task.wait(gameSettings.transitionTime)テストサーバー を開始し、プレイヤーが時間切れと勝利条件のメッセージを見るかどうかをチェックします。
トラブルシューティングのヒント
この時点で、メッセージを見ることはできません。以下の 1つを試してください。
- エラーが「発見されました」のエンドステータスメッセージが表示されている場合は、条件のいずれも成功しませんでした。コードを MatchManager.getEndStatus() 対してチェックします。
- エンドステータスが表示されない場合は、task.wait(gameSettings.transitionTime) がメッセージを送信した後にあることを確認してください。
新しいマッチを開始する
新しいマッチを開始する前に、ブリーフなロードインがあります。これにより、プレイヤーはエンドステータスを見る時間があり、ロビーへテレポートするのが少しずつ感じられます。
トランジションの終了に伴い、残りのプレイヤーはアリーナから再設定除され、すべてのコードがリセットされます。これにより、プレイヤーはクリーンなバージョンのゲームで次のマッチを開始します。
トランジョンを処理する
プレイヤーがトランジション状態に移動すると、武器を取り上げます。
PlayerManager で、ローカル関数を見つけます。コードをコピーして、下の removePlayerWeapon() の下に貼り付けます。コードは、アクティブに装備されているまたはプレイヤーのバックパックにある個々のプレイヤーの武器を削除します。
local function removePlayerWeapon(whichPlayer)-- プレイヤーが切断されたか、退出したかどうかを確認します。if whichPlayer thenlocal character = whichPlayer.Character-- プレイヤーがそれを現在、そのキャラクターに持っている場合local weapon = character:FindFirstChild("Weapon")if weapon thenweapon:Destroy()end-- プレイヤーがバックパックに武器を持っている場合local backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")if backpackWeapon thenbackpackWeapon:Destroy()endelseprint("No player to remove weapon")endend新しいモジュール機能の開始名は removeAllWeapons() です。
function PlayerManager.removeAllWeapons()end-- イベントPlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerその関数で、for ループを使用してアクティブなプレイヤー テーブルを通過します。ループで、removePlayerWeapon() を呼び出し、見つかったプレイヤーをパスする という名前のプレイヤーをパスします。
function PlayerManager.removeAllWeapons()for playerKey, whichPlayer in activePlayers doremovePlayerWeapon(whichPlayer)endend
マッチの間の清掃
清掃は MatchManager の独自の機能です。清掃は、以前に作成された関数を使用してプレイヤーの武器を削除します。ゲームを拡大するにつれて、マップをリセットするなど、さまざまな機能が追加されます。
Open MatchManager。新しいモジュール機能を追加します cleanupMatch()。その機能で、playerManager.removeAllWeapons() を呼び出します。
function MatchManager.cleanupMatch()playerManager.removeAllWeapons()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManager次に、クリーンアップ関数を呼び出します。Open GameManager を開き、matchManager.cleanupMatch() を見つけます。その後、最後の task.wait() を呼び出す前に 1> matchManager.cleanMatch1> を呼び出します。
while true dodisplayManager.updateStatus("Waiting for Players")repeattask.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersdisplayManager.updateStatus("Get ready!")task.wait(gameSettings.transitionTime)matchManager.prepareGame()local endState = matchEnd.Event:Wait()local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)matchManager.cleanupMatch()task.wait(gameSettings.transitionTime)endテストサーバーを開始し、マッチを実行します。タイマーが切れるまで待ち、プレイヤーの武器が終了ゲーム中に削除されたことを確認します。
マッチをリセット中
ゲーム内でいくつかの他のことに気づいたかもしれません。たとえば、プレイヤーがマッチ終了後にアリーナに残っていることがあります。マッチをクリーンアップした後、ゲームを再設定します。これには、プレイヤーをアリーナに送り戻すことと、アクティブなプレイヤーのテーブルをクリアすることが含まれます。リセットが完了すると、ゲーム
まず、ロビーにプレイヤーを送り戻す関数を開始します。
PlayerManager で:
- Create a module function named resetPlayers() 。
- ActivePlayers をループで反復する for を追加します。
- ループで respawnPlayerInLobby() を呼び出し、パラメーターとしてプレイヤーをパスします。
function PlayerManager.resetPlayers()for playerKey, whichPlayer in activePlayers dorespawnPlayerInLobby(whichPlayer)endend-- イベントPlayers.PlayerAdded:Connect(onPlayerJoin)return PlayerManageractivePlayers テーブルを空にすることで、次のマッチのために、{} と同じに設定して、空のテーブルをリセットする方法です。
function PlayerManager.resetPlayers()for playerKey, whichPlayer in activePlayers dorespawnPlayerInLobby(whichPlayer)endactivePlayers = {}endOpen MatchManager。コード a new module function named resetMatch() と playerManager.resetPlayers() を呼び出します。
function MatchManager.resetMatch()playerManager.resetPlayers()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerGameManager に戻ります。matchManager.resetMatch() true を呼び出します。
while true dodisplayManager.updateStatus("Waiting for Players")repeattask.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersdisplayManager.updateStatus("Get ready!")task.wait(gameSettings.transitionTime)matchManager.prepareGame()local endState = matchEnd.Event:Wait()local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)matchManager.cleanupMatch()task.wait(gameSettings.transitionTime)matchManager.resetMatch()endテストサーバーを開始し、マッチを実行します。 2つのゲームループを通過できることを確認してください。
完了したスクリプト
以下は、作業を確認するために完了したスクリプトです。
GameManager スクリプト
-- サービス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 displayManager = require(moduleScripts:WaitForChild("DisplayManager"))-- イベントlocal events = ServerStorage:WaitForChild("Events")local matchEnd = events:WaitForChild("MatchEnd")while true dodisplayManager.updateStatus("Waiting for Players")repeattask.wait(gameSettings.intermissionDuration)until #Players:GetPlayers() >= gameSettings.minimumPlayersdisplayManager.updateStatus("Get ready!")task.wait(gameSettings.transitionTime)matchManager.prepareGame()local endState = matchEnd.Event:Wait()local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)matchManager.cleanupMatch()task.wait(gameSettings.transitionTime)matchManager.resetMatch()end
MatchManager スクリプト
local MatchManager = {}
-- サービス
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- モジュールスクリプト
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
local timer = require(moduleScripts:WaitForChild("Timer"))
-- イベント
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- 値
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- マッチ時間を追跡するために使用する新しいタイマーオブジェクトを作成します。
local myTimer = timer.new()
-- ローカル関数
local function stopTimer()
myTimer:stop()
end
local function timeUp()
matchEnd:Fire(gameSettings.endStates.TimerUp)
end
local function startTimer()
myTimer:start(gameSettings.matchDuration)
myTimer.finished:Connect(timeUp)
while myTimer:isRunning() do
-- +1 を追加すると、タイマーが 0 ではなく 1 で表示されるようになります。
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- 待ち時間を設定しないと、より正確なループオファーが提供されます
task.wait()
end
end
-- モジュール機能
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
function MatchManager.getEndStatus(endState)
local messageToReturn
if endState == gameSettings.endStates.FoundWinner then
local winnerName = playerManager.getWinnerName()
messageToReturn = "Winner is : " .. winnerName
elseif endState == gameSettings.endStates.TimerUp then
messageToReturn = "Time ran out!"
else
messageToReturn = "Error found"
end
return messageToReturn
end
function MatchManager.cleanupMatch()
playerManager.removeAllWeapons()
end
function MatchManager.resetMatch()
playerManager.resetPlayers()
end
matchStart.Event:Connect(startTimer)
matchEnd.Event:Connect(stopTimer)
return MatchManager
PlayerManager スクリプト
local PlayerManager = {}
-- サービス
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- モジュール
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- イベント
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
-- マップ変数
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- 値
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
-- プレイヤー変数
local activePlayers = {}
local playerWeapon = ServerStorage.Weapon
local function checkPlayerCount()
if #activePlayers == 1 then
matchEnd:Fire(gameSettings.endStates.FoundWinner)
print("Found winner")
end
end
local function removeActivePlayer(player)
print("removing player")
for playerKey, whichPlayer in activePlayers do
if whichPlayer == player then
table.remove(activePlayers, playerKey)
playersLeft.Value = #activePlayers
checkPlayerCount()
end
end
end
local function respawnPlayerInLobby(player)
player.RespawnLocation = lobbySpawn
player:LoadCharacter()
end
local function preparePlayer(player, whichSpawn)
player.RespawnLocation = whichSpawn
player:LoadCharacter()
local character = player.Character or player.CharacterAdded:Wait()
-- プレイヤーにツールを与える
local sword = playerWeapon:Clone()
sword.Parent = character
local humanoid = character:WaitForChild("Humanoid")
humanoid.Died:Connect(function()
respawnPlayerInLobby(player)
removeActivePlayer(player)
end)
end
local function onPlayerJoin(player)
player.RespawnLocation = lobbySpawn
end
local function removePlayerWeapon(whichPlayer)
-- プレイヤーが切断されたか、退出したかどうかを確認します。
if whichPlayer then
local character = whichPlayer.Character
-- プレイヤーがそれを現在、そのキャラクターに持っている場合
local weapon = character:FindFirstChild("Weapon")
if weapon then
weapon:Destroy()
end
-- プレイヤーがバックパックに武器を持っている場合
local backpackWeapon = whichPlayer.Backpack:FindFirstChild("Weapon")
if backpackWeapon then
backpackWeapon:Destroy()
end
else
print("No player to remove weapon")
end
end
function PlayerManager.sendPlayersToMatch()
local availableSpawnPoints = spawnLocations:GetChildren()
for playerKey, whichPlayer in Players:GetPlayers() do
table.insert(activePlayers,whichPlayer)
-- スポーン場所を取得し、次のプレイヤーが次のスポーンを得るようにテーブルから削除します
local spawnLocation = table.remove(availableSpawnPoints, 1)
preparePlayer(whichPlayer, spawnLocation)
end
playersLeft.Value = #activePlayers
end
function PlayerManager.getWinnerName()
local winningPlayer = activePlayers[1]
if winningPlayer then
return winningPlayer.Name
else
return "Error: No player found"
end
end
function PlayerManager.removeAllWeapons()
for playerKey, whichPlayer in activePlayers do
removePlayerWeapon(whichPlayer)
end
end
function PlayerManager.resetPlayers()
for playerKey, whichPlayer in activePlayers do
respawnPlayerInLobby(whichPlayer)
end
activePlayers = {}
end
-- イベント
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager