ทำความสะอาดและรีเซ็ต

*เนื้อหานี้แปลโดยใช้ AI (เวอร์ชัน Beta) และอาจมีข้อผิดพลาด หากต้องการดูหน้านี้เป็นภาษาอังกฤษ ให้คลิกที่นี่

ถึงเวลาที่ต้องเขียนโค้ดขั้นสุดท้ายของเกม: ทำความสะอาดและรีเซ็ตโค้ดในขั้นตอนนี้ช่วยให้แบบจำลองเกมหยุดชะงักและการแข่งขันในอนาคตเริ่มต้นเหมือนกันสำหรับผู้เล่นแต่ละคน

อัปเดต GUI

ก่อนทำการล้างและรีเซ็ต แจ้งผู้เล่นว่าเกมสิ้นสุดลงอย่างไรโดยใช้ DisplayManager เพื่อแสดงสถานะที่เหมาะสม

รับชื่อผู้ชนะ

เริ่มต้นโดยรับชื่อผู้เล่นที่ชนะถ้ามีหนึ่งก่อนหน้านี้โค้ดตรวจสอบว่าขนาดของตารางผู้เล่นที่ใช้งานลดลงเหลือ 1เพื่อรับชื่อผู้เล่นที่เหลือให้กลับชื่อในดัชนีแรกของตารางนั้น

  1. ใน PlayerManager เริ่มฟังก์ชันโมดูลใหม่ชื่อ getWinnerName()


    function PlayerManager.getWinnerName()
    end
    -- อีเวนต์
    Players.PlayerAdded:Connect(onPlayerJoin)
  2. เพิ่มข้อแม้ถ้าที่จะทำงานหากมีบางอย่างอยู่ใน activePlayers[1]แม้ว่าจะตรวจสอบจํานวนโต๊ะก่อนแล้ว แต่ผู้เล่นอาจถูกตัดการเชื่อมต่อหรือออกจากเกม


    function PlayerManager.getWinnerName()
    local winningPlayer = activePlayers[1]
    if winningPlayer then
    end
    end
  3. ในข้อความ if:

    • ส่งคืนชื่อผู้เล่น
    • สำหรับส่วนที่เหลือให้คืนสตริงข้อผิดพลาด

    function PlayerManager.getWinnerName()
    local winningPlayer = activePlayers[1]
    if winningPlayer then
    return winningPlayer.Name
    else
    return "Error: No winning player found"
    end
    end

รับสถานะสิ้นสุด

ใช้ฟังก์ชันโมดูลเพื่อรับข้อมูลจากสถานะสิ้นสุดที่ถูกต้อง ไม่ว่าจะเป็นการสิ้นสุดของเวลาหรือผู้เล่นคนหนึ่งถูกทอดทิ้งจากนั้นส่งตัวแปรสถานะนั้นไปยัง DisplayManager เพื่ออัปเดตสถานะ GUI ด้วยข้อความที่เหมาะสม

  1. ใน MatchManager รหัสฟังก์ชันโมดูลใหม่ที่มีชื่อ getEndStatus() ด้วยพารามิเตอร์ชื่อ endStateเพื่อเก็บข้อความที่จะส่ง เพิ่มตัวแปรว่างเปล่าชื่อ statusToReturn


    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    matchStart:Fire()
    end
    function MatchManager.getEndStatus(endState)
    local statusToReturn
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  2. ตั้งค่าของ statusToReturn โดยใช้ if และ elseif สถานะตรวจสอบตัวแปรสถานะสิ้นสุด: FoundWinner และ TimerUpสำหรับการตรวจสอบข้อผิดพลาด รวมอื่นๆ ที่ด้านท้าย


    function MatchManager.getEndStatus(endState)
    local statusToReturn
    if endState == gameSettings.endStates.FoundWinner then
    elseif endState == gameSettings.endStates.TimerUp then
    else
    end
    end
  3. เพิ่มสิ่งต่อไปนี้สำหรับแต่ละเงื่อนไข:

    FoundWinner

    • ตัวแปรสำหรับผู้ชนะที่ใช้ playerManager.getWinnerName() .
    • อัปเดต statusToReturn ด้วยสตริงที่ประกาศผู้ชนะ

    TimerUp

    • อัปเดต statusToReturn ด้วยสตริงที่ประกาศเวลาหมดลง

    Else

    • อัปเดต statusToReturn ด้วยข้อความแจ้งข้อผิดพลาดในกรณีที่มีปัญหาในการรับข้อความเกมสุดท้าย

    function MatchManager.getEndStatus(endState)
    local statusToReturn
    if endState == gameSettings.endStates.FoundWinner then
    local winnerName = playerManager.getWinnerName()
    statusToReturn = "Winner is : " .. winnerName
    elseif endState == gameSettings.endStates.TimerUp then
    statusToReturn = "Time ran out!"
    else
    statusToReturn = "Error found"
    end
    end
  4. ส่งข้อความกลับโดยพิมพ์ return statusToReturn


    function MatchManager.getEndStatus(endState)
    local statusToReturn
    if endState == gameSettings.endStates.FoundWinner then
    local winnerName = playerManager.getWinnerName()
    statusToReturn = "Winner is : " .. winnerName
    elseif endState == gameSettings.endStates.TimerUp then
    statusToReturn = "Time ran out!"
    else
    statusToReturn = "Error found"
    end
    return statusToReturn
    end

แสดงและทดสอบ

รับการประกาศอัปเดตใน GameManager และแสดงให้กับผู้เล่นที่ใช้ DisplayManager

  1. เปิด GameManager ในขณะที่ทำซ้ำจริง do ลูป, ลบ คำสั่งพิมพ์ล่าสุดจากนั้นสร้างตัวแปรชื่อ endStatusตั้งค่าให้เท่ากับการโทร matchManager.getEndStatus(endState)


    while true do
    displayManager.updateStatus("Waiting for Players")
    repeat
    task.wait(gameSettings.intermissionDuration)
    until #Players:GetPlayers() >= gameSettings.minimumPlayers
    displayManager.updateStatus("Get ready!")
    task.wait(gameSettings.transitionTime)
    matchManager.prepareGame()
    local endState = matchEnd.Event:Wait()
    local endStatus = matchManager.getEndStatus(endState)
    end
  2. เพื่อแสดงข้อความที่ส่งกลับในป้าย GUI โทร displayManager.updateStatus() และส่ง endStatus


    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
  3. ดังนั้นเกมจะหยุดเพื่อให้ผู้เล่นเห็นข้อความ เพิ่มการรอด้วย transitionTime


    local endStatus = matchManager.getEndStatus(endState)
    displayManager.updateStatus(endStatus)
    task.wait(gameSettings.transitionTime)
  4. เริ่มต้นเซิร์ฟเวอร์ทดสอบ และตรวจสอบว่าผู้เล่นเห็นข้อความต่อไปสำหรับเวลาขึ้นและเงื่อนไขผู้เล่นที่ชนะ

    เงื่อนไขเวลาหมดลง
    เงื่อนไขผู้เล่นที่ชนะ

เคล็ดลับการแก้ปัญหา

ในจุดนี้คุณไม่สามารถดูข้อความได้, ลองหนึ่งในต่อไปนี้

  • หากข้อความสถานะสิ้นสุดของคุณคือ "พบข้อผิดพลาด" ไม่มีเงื่อนไขใดที่ประสบความสำเร็จ ตรวจสอบโค้ดใน MatchManager.getEndStatus() กับตัวอย่างโค้ด
  • หากสถานะสิ้นสุดไม่แสดง ตรวจสอบว่า task.wait(gameSettings.transitionTime) อยู่หลังจากส่งข้อความไปยัง displayManager

เริ่มการแข่งขันใหม่

ก่อนเริ่มการแข่งขันใหม่จะมีการเปลี่ยนผ่านสั้น ๆสิ่งนี้ทำให้ผู้เล่นมีเวลาดูสถานะสิ้นสุดและทำให้การถูกเทเลพอร์ตไปยังล็อบบี้รู้สึกน้อยลงฉับพลัน

เมื่อสิ้นสุดการเปลี่ยนผ่านแล้ว ผู้เล่นที่เหลือจะถูกลบออกจากสนามแข่งและรหัสทั้งหมดจะรีเซ็ตซึ่งจะช่วยให้ผู้เล่นเริ่มการแข่งขันครั้งต่อไปด้วยเวอร์ชันที่สะอาดของเกม

จัดการการเปลี่ยนผ่าน

เมื่อผู้เล่นย้ายไปสู่สถานะการเปลี่ยนผ่าน ให้ลบอาวุธของพวกเขา

  1. ใน PlayerManager ค้นหาฟังก์ชันท้องถิ่นคัดลอกและวางโค้ดที่เน้นไว้สำหรับ removePlayerWeapon() ด้านล่างโค้ดจะลบอาวุธของผู้เล่นรายเดียวหากมันถูกติดตั้งอย่างใช้งานหรืออยู่ในกระเป๋าเป้สะพายหลังของผู้เล่น


    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
  2. เริ่มฟังก์ชันโมดูลใหม่ชื่อ removeAllWeapons()


    function PlayerManager.removeAllWeapons()
    end
    -- อีเวนต์
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  3. ในฟังก์ชันนั้นใช้ลูป for เพื่อไปผ่านตารางผู้เล่นที่ใช้งานอยู่ ในลูปเรียก removePlayerWeapon() และส่งผู้เล่นที่พบ


    function PlayerManager.removeAllWeapons()
    for playerKey, whichPlayer in activePlayers do
    removePlayerWeapon(whichPlayer)
    end
    end

ทำความสะอาดระหว่างการแข่งขัน

การล้างจะเป็นฟังก์ชันของตัวเองใน MatchManagerสําหรับตอนนี้การล้างจะใช้ฟังก์ชันที่สร้างไว้ล่วงหน้าเพื่อลบอาวุธผู้เล่นเท่านั้นเมื่อคุณขยายเกม สามารถเพิ่มได้มากขึ้น เช่น ฟังก์ชันที่จะรีเซ็ตแผนที่ที่เปลี่ยนแปลงในระหว่างการแข่งขัน

  1. เปิด MatchManager เพิ่มฟังก์ชันโมดูลใหม่ชื่อ cleanupMatch() ในฟังก์ชันนั้น โทร playerManager.removeAllWeapons()


    function MatchManager.cleanupMatch()
    playerManager.removeAllWeapons()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  2. ต่อไปให้เรียกฟังก์ชันการล้างข้อมูลเปิด GameManager และค้นหาในขณะที่จริงทำซ้ำลูปดังนั้นผู้เล่นจะไม่มีอาวุธถูกลบในระหว่างช่วงพักระหว่างการแข่งขัน โทร matchManager.cleanupMatch() ก่อนที่จะเป็นครั้งสุดท้าย task.wait()


    while true do
    displayManager.updateStatus("Waiting for Players")
    repeat
    task.wait(gameSettings.intermissionDuration)
    until #Players:GetPlayers() >= gameSettings.minimumPlayers
    displayManager.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
  3. เริ่มเซิร์ฟเวอร์ทดสอบและทำการแข่งขัน รอให้เวลาหมดลงและยืนยันว่าอาวุธของผู้เล่นถูกลบออกในระหว่างช่วงพักระหว่างเกม

    ในระหว่างการแข่งขัน
    หลังการแข่งขัน

รีเซ็ตการจับคู่

คุณอาจสังเกตเห็นสิ่งอื่นๆ อีกไม่กี่อย่างในเกม เช่น ผู้เล่นยังคงอยู่ในสนามแข่งหลังจากการแข่งขันสิ้นสุดเมื่อล้างการแข่งขันเสร็จแล้ว รีเซ็ตเกมต่อไปซึ่งรวมถึงการส่งผู้เล่นในสนามกลับไปที่ล็อบบี้และล้างโต๊ะผู้เล่นที่ใช้งานเมื่อรีเซ็ตอยู่แล้ว วงจรเกมสามารถทำงานได้อย่างไม่มีกำหนด

ก่อนอื่นเริ่มฟังก์ชันเพื่อส่งผู้เล่นกลับไปที่ล็อบบี้

  1. ใน PlayerManager:

    • สร้างฟังก์ชันโมดูลชื่อ resetPlayers()
    • เพิ่มลูป for เพื่อทำซ้ำผ่านผู้เล่นที่ใช้งานอยู่
    • ในลูปเรียก respawnPlayerInLobby() และส่งผู้เล่นเป็นพารามิเตอร์

    function PlayerManager.resetPlayers()
    for playerKey, whichPlayer in activePlayers do
    respawnPlayerInLobby(whichPlayer)
    end
    end
    -- อีเวนต์
    Players.PlayerAdded:Connect(onPlayerJoin)
    return PlayerManager
  2. ตรวจสอบให้แน่ใจว่าตาราง activePlayers ว่างเปล่าสำหรับการแข่งขันถัดไปโดยตั้งค่าให้เท่ากับ {} ซึ่งเป็นวิธีที่รวดเร็วในการรีเซ็ตไปยังตารางว่างเปล่า


    function PlayerManager.resetPlayers()
    for playerKey, whichPlayer in activePlayers do
    respawnPlayerInLobby(whichPlayer)
    end
    activePlayers = {}
    end
  3. เปิด MatchManager เขียนฟังก์ชันโมดูลใหม่ชื่อ resetMatch() และเรียก playerManager.resetPlayers()


    function MatchManager.resetMatch()
    playerManager.resetPlayers()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  4. กลับไปที่ ผู้จัดการเกม . ในตอนท้ายของลูป while true เรียก matchManager.resetMatch()


    while true do
    displayManager.updateStatus("Waiting for Players")
    repeat
    task.wait(gameSettings.intermissionDuration)
    until #Players:GetPlayers() >= gameSettings.minimumPlayers
    displayManager.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
  5. เริ่มเซิร์ฟเวอร์ทดสอบและทำการแข่งขัน ยืนยันว่าคุณสามารถผ่านเกมลูปได้อย่างน้อยสองรอบโดยไม่มีข้อผิดพลาด

สคริปต์สําเร็จ

ด้านล่างเป็นสคริปต์ที่เสร็จสมบูรณ์เพื่อตรวจสอบงานของคุณอีกครั้ง

สคริปต์ 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 do
displayManager.updateStatus("Waiting for Players")
repeat
task.wait(gameSettings.intermissionDuration)
until #Players:GetPlayers() >= gameSettings.minimumPlayers
displayManager.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 = (myTimer:getTimeLeft() + 1) // 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

สคริปต์ผู้จัดการผู้เล่น


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