ถึงเวลาเขียนโค้ดส่วนสุดท้ายของเกม: ทำความสะอาดและรีเซ็ต โค้ดในส่วนนี้รับประกันว่าเกมจะเป็นลูปไปยังช่วงพักสุดท้ายและการแข่งขันในอนาคตจะเริ่มเดียวสำหรับผู้เล่นแต่ละราย
การปรับปรุง GUI
ก่อนที่จะทำความสะอาดและรีเซ็ต ให้ผู้เล่นทราบว่าเกมจบลงโดยใช้ DisplayManager เพื่อแสดงสถานะที่เหมาะสม
รับชื่อผู้ชนะ
เริ่มต้นด้วยการรับชื่อผู้เล่นที่ชนะหากมีหนึ่ง ก่อนหน้านี้ โค้ดจะตรวจสอบว่าขนาดของตารางผู้เล่นที่เปิดอยู่ลดลงเหลือ 1 หากต้องการรับชื่อผู้เล่นที่เหลือให้กลับชื่อที่ตรงของตาราง
ใน PlayerManager เริ่มโครงสร้างโมดูลใหม่ที่มีชื่อว่า getWinnerName()
function PlayerManager.getWinnerName()end-- เหตุการณ์Players.PlayerAdded:Connect(onPlayerJoin)ใส่ if ที่วิ่งเมื่อมีสิ่งอื่น ๆ ใน activePlayers[1] แม้ว่าจะตรวจสอบจำนวนโต๊ะก่อนหน้านี้ก็ตาม ผู้เล่นอาจได้ตัดการเชื่อมต่อหรือออกจากเกม
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
รับสถานะจุดสิ้นสุด
ใช้หน้าโมดูลเพื่อรับข้อมูลจากสถานะที่ถูกต้อง ไม่ว่าจะเป็นผู้เล่นคนสุดท้ายหรือไม่ จากนั้นส่งตัวแปรสถานะนี้ไปยัง DisplayManager เพื่อปรับปรุง GUI สถานะด้วยข้อความที่เหมาะสม
ใน 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 MatchManagerตั้งค่าของ statusToReturn โดยใช้ if และถ้าและถ้า. ตรวจสอบตัวแปรสถานะจุดสิ้นสุด: FoundWinner และ TimerUp สำหรับการตรวจสอบข้อผิดพลาด ปิด.
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"endendส่งกลับข้อความโดยการพิมพ์ return 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
เปิด GameManager ในขณะที่จริงเป็นข้อเเบบเเบบพิมพ์สุดท้าย ลบ สตามประการพิมพ์สุดท้าย แล้วสร้างตัวแปรที่มีชื่อว่า endStatus ตั้งเป็นตัวเท่ากับการเรียก 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)endเพื่อแสดงข้อความที่กลับมาในแท็งก์เป็นข้อความใน GUI โปรดโทร displayManager.updateStatus() และผ่านใน endStatus
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)ดังนั้นเกมจึงหยุดเพื่อให้ผู้เล่นเห็นข้อความ, เพิ่มการรอด้วย transitionTime
local endStatus = matchManager.getEndStatus(endState)displayManager.updateStatus(endStatus)task.wait(gameSettings.transitionTime)เริ่มเซิร์ฟเวอร์ทดสอบ และตรวจสอบว่าผู้เล่นเห็นข้อความต่อไปนี้สำหรับเวลาของการทดสอบและเงื่อนไขของผู้ชนะ
เคล็ดลับการแก้ปัญหา
ในขณะนี้คุณไม่สามารถดูข้อความได้ ลองใช้หนึ่งในตัวเลือกด้านล่าง
- หากข้อความสถานะท้ายของคุณคือ "พบข้อผิดพลาด" ไม่มีเงื่อนไขใด ๆ สำเร็จ ตรวจสอบโค้ดใน 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 ตรงกันเมื่อคุณขยายเกม มากขึ้น สามารถเพิ่มได้ตัวอื่น เช่น ฟังก์ชันท
เปิด MatchManager ใหม่ โดยเพิ่มหน้าโมดูลใหม่ที่มีชื่อว่า cleanupMatch() ในหน้าโมดูลนั้น เรียก playerManager.removeAllWeapons() ในหน้าโมดูลนั้น
function MatchManager.cleanupMatch()playerManager.removeAllWeapons()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerต่อไป, โทรหาคุณสมบัติล้าง. เปิด GameManager และหาขณะที่จริงทำซ้ำ. ดังนั้นผู้เล่นจึงมีอาวุธถูกลบออกในระหว่างช่วงพักในตอนท้าย, โทร matchManager.cleanupMatch() ก่อนที่จะล่าสุด Library
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:
- สร้างหน้าโปรโมจูลที่มีชื่อว่า resetPlayers()
- เพิ่ม for เพื่อทำซ้ำผ่านผู้เล่นที่ใช้งานอยู่
- ในล็อป, โทร respawnPlayerInLobby() และส่งผู้เล่นเป็นพารามิเตอร์
function PlayerManager.resetPlayers()for playerKey, whichPlayer in activePlayers dorespawnPlayerInLobby(whichPlayer)endend-- เหตุการณ์Players.PlayerAdded:Connect(onPlayerJoin)return PlayerManagerให้แน่ใจว่าตาราง activePlayers ว่างเปล่าสำหรับการแข่งขันครั้งต่อไปโดยการตั้งค่าให้เท่ากับ {} ซึ่งเป็นวิธีที่รวดเร็วในการรีเซ็ตไปยังตารางที่ว่างเปล่า
function PlayerManager.resetPlayers()for playerKey, whichPlayer in activePlayers dorespawnPlayerInLobby(whichPlayer)endactivePlayers = {}endเปิด MatchManager โดยใช้รหัสโมดูลใหม่ที่มีชื่อว่า resetMatch() และโทร playerManager.resetPlayers()
function MatchManager.resetMatch()playerManager.resetPlayers()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerกลับไปที่ GameManager ในตอนท้ายของเวลาจริง โดยมีการเรียก matchManager.resetMatch() คือ
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เริ่มเซิร์ฟเวอร์ทดสอบและดำเนินการแข่งขัน ยืนยันว่าคุณสามารถผ่านผ่านสองสเต็ปเกมโดยไม่มีข้อผิดพลาดได้อย่างน้อย
สคริปที่สำเร็จ
ด้านล่างเป็นสคริปต์ที่สำเร็จแล้วเพื่อตรวจสอบงานของคุณ
สคริปต์ 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 จะให้แน่ใจว่าตัวนับจะแสดงเวลาที่ 1 แทนที่จะเป็น 0
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