การจบการแข่งขัน

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

ห้องสามารถจบลงได้ในเงื่อนไขบางอย่างรวมถึงเวลาที่หมดอายุหรือผู้เล่นคนเดียวที่ถูกทิ้งไว้

การจัดการผู้เล่นที่แพ้

ตอนนี้ผู้เล่นที่เอาชนะจะเกิดใหม่ในอารีน่า ตรงกัน

  1. ใน PlayerManager สร้างฟังก์ชันในชื่อ respawnPlayerInLobby() กำลังติดตาม:
  • ตั้งค่าโครงสร้าง RespawnLocation ของผู้เล่นให้เป็นล็อบบี้Spawn
  • Reload ตัวละครด้วย Player:LoadCharacter() อย่าลืม, LoadCharacter() จะสร้างผู้เล่นใหม่ที่พวกเขาสปอน, กำจัดเครื่องมือใด ๆ ที่พวกเขามี

ใช้คุณสมบัติทั่วไป

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

พิจารณาสิ่งนี้: เพื่อเริกผู้เล่นที่ถูกทําลายไปยังล็อบบี้ ฟังก์ชัน respawn จะต้องเชื่อมต่อกับอีเวนต์ Died ของผู้เล่น มีปัญหาอยู่ที่นี่ หากคุณเชื่อมต่ออีเวนต

เพื่อรับชื่อผู้เล่นที่เหยียดเหตุการณ์ตาย, ใช้ฟังก์ชันอันโดยแอนได้ ฟังก์ชันอันโดยแอนไม่มีชื่อ, และสามารถสร้างได้โดยตรงภายใน Connect() แทนที่จะสร้างเป็นคู่คี่

ตัวอย่างฟังก์ชันที่ไม่ระบุชื่อด้านล่างแสดงให้เห็นภาษา


myPlayer.Died:Connect(function()
print(player)
end)

การเขียนเหตุการณ์ที่ตาย

สำหรับคุณสมบัตินี้ เมื่อตัวละครของผู้เล่นตาย พวกเขาจะเรียกใช้งานที่เรียกคืนพวกเขา

  1. เพื่อเข้าถึงกิจกรรมของผู้เล่นที่ Died ใน PlayerManager > preparePlayer() เพิ่มตัวแปรสำหรับมนุษย์ของผู้เล่น


    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")
    end
  2. สร้างคุณสมบัติที่ปลอมติดต่อกับเหตุการณ์ Died เริ่มต้นโดยการพิมพ์ humanoid.Died:Connect() แล้ว, ใน ภายใน Connect() แล้ว, ใน 1> ภายใน</


    local humanoid = character:WaitForChild("Humanoid")
    humanoid.Died:Connect(function()
    end)
  3. ในคุณสมบัติที่ไม่ระบุ, โทร respawnPlayerInLobby() . ผ่านใน player ตรงกัน


    local humanoid = character:WaitForChild("Humanoid")
    humanoid.Died:Connect(function()
    respawnPlayerInLobby(player)
    end)
  4. เริ่มเซิร์ฟเวอร์ ตรงกันและทดสอบว่าเมื่อผู้เล่นตายพวกเขาจะเกิดใหม่ในล็อบบี้ เพื่อเอาชนะผู้เล่นให้เดินไปยังพวกเขาและใช้อาวุธของคุณจนกว่าคุณจะสามารถยืนยันได้ว่าพ

    กำลังโจมตีผู้เล่น 2
    ผู้เล่น 2 ในล็อบบี้หลังจาก respawn

หมายเหตุ, นอกจากนี้ยังมีวิธีการทดสอบที่แตกต่างกันหากต้องการ

  • เพื่อฆ่าผู้เล่นใน Server > หน้าต่างออก > บาร์คําสั่ง คัดลอกและวาง: workspace.Player1.Humanoid.Health = 0 กด Enter เพื่อดําเนินการคําสั่ง การลบผู้เล่นอื่น ๆ ใช้ Player2, Player3, etc.
  • การตั้งค่า GameSettings > matchDuration ในเวลานานขึ้นสามารถให้เวลามากขึ้นสำหรับคุณเพื่อให้คุณมีเวลามากขึ้นในการค้นหาและการกำจัดผู้เล่นทั้งหมด
  • เพื่อทดสอบเร็วขึ้น เปลี่ยน GameSettings > minimumPlayers เป็นตัวเลขที่เล็กกว่าเช่น 2

การจบเกม

ตอนนี้ผู้เล่นที่ถูกทําลายกลับมาที่ที่ทํางานแล้วเริ่มต้นทํางานในการจบเกม จําได้ว่าการสร้างเหตุการณ์ MatchEnd เมื่อเวลาหมดหรือผู้ชนะถูกพบ

เพื่อบอกค่าอื่น ๆ ที่เป็นเงื่อนไขสิ้นสุดเกมส์ สร้างตารางที่มีแปรนามสกุลสำหรับ TimerUp และ FoundWinner เมื่อเหตุการณ์สิ้นสุดเกมส์เกิดขึ้น มันจะผ่านในแปรนามสกุลเพื่อให้ค

  1. ใน GameSettings สร้างโครงสร้างโมดูลที่ว่างขึ้นชื่อว่า endStates


    local GameSettings = {}
    -- แปรแกม
    GameSettings.intermissionDuration = 5
    GameSettings.matchDuration = 10
    GameSettings.minimumPlayers = 2
    GameSettings.transitionTime = 5
    -- ปิด
    GameSettings.endStates = {
    }
    return GameSettings
  2. สร้างสองแป้นที่มีชื่อว่า TimerUp และ FoundWinner ตั้งแต่แป้นเหล่านี้จะถูกใช้เพื่อทดสอบรหัส เหล่านี้จะถูกใช้เพื่อทดสอบรหัส


GameSettings.endStates = {
TimerUp = "TimerUp",
FoundWinner = "FoundWinner"
}

สิ้นสุดด้วย Timer

เมื่อเวลาจะหมด ให้ยิงเหตุการณ์ "จุดสิ้นสุด" และส่งตัวแปรสถานะ "จุดสิ้นสุด" ที่ตรงกัน ด้วยวิธีนี้ สคริปต์อื่นที่ฟังสำหรับเหตุการณ์นั้นจะสามารถตอบสนองได้ตาม

  1. ใน GameManager ในขณะที่จริงจังโดยทรูปแบบต่อทวีคูณ, ค้นหาสาย matchEnd.Event:Wait() ต้นสาย เริ่มต้นของสาย, เพิ่ม local 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()
    end
  2. เพื่อยืนยันว่าได้รับสถานะที่ถูกต้อง ให้เพิ่มคำพิมพ์ที่รวมถึง 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()
    print("Game ended with: " .. endState)
    end
  3. ใน MatchManager ค้นหา timeUp() และ ลบ สตริงพิมพ์ จากนั้นในการเปิดตัวเหตุการณ์สิ้นสุดของการจับคู่ให้พิมพ์ matchEnd:Fire() และส่งผ่าน 1> gameSettings.endStates.TimerUp1>


    -- มูลค่า
    local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
    local timeLeft = displayValues:WaitForChild("TimeLeft")
    -- สร้างวัตถุจับเวลาใหม่ที่จะใช้เพื่อติดตามเวลาการแข่งขัน
    local myTimer = timer.new()
    -- หน้าต่างท้องถิ่น
    local function timeUp()
    matchEnd:Fire(gameSettings.endStates.TimerUp)
    end
  4. ทดสอบการจับคู่ เมื่อเวลาจะหมดตรวจสอบว่าคำพิมพ์รวมถึงสตริงที่เก็บไว้ในตัวแปร TimerUp

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

ในขณะนี้ข้อความนี้ไม่ได้แสดงขึ้น ลองใช้หนึ่งในต่อไปนี้

  • ตรวจสอบว่าทุกที่ที่แปรแกนสถานะจุดสิ้นสุดถูกเรียกว่าอยู่ที่ไหน พวกเขาถูกเขียนอย่างถูกต้องเช่นนี้: gameSettings.endStates.TimerUp .
  • ให้แน่ใจว่าใช้ : (ตัวอักษรประกอบ) กับ Fire() แทน ของดอตอุปกรณ์, เช่นใน matchEnd:Fire()

การเขียนการแข่งขันชนะ

ต่อไป, สคริปต์จำเป็นต้องระบุผู้ชนะ, ลบผู้เล่นที่แพ้, และดำเนินการทำความสะอาดเช่นการหยุดนาฬิกา หากเงื่อนไข FoundWinner ไม่ตรงตาม, คุณจะต้องฟังก์ชั่นที่ตรวจส

การตรวจสอบจำนวนผู้เล่น

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

  1. ใน PlayerManager จัดเตรียมแปรไฟล์ต่อไปนี้:

    • โฟลเดอร์ModuleScripts
    • โมดูล GameSettings - ใช้สำหรับเข้าถึงแปรสถานะท้ายสุด
    • หน้าเหตุการณ์และกิจกรรม MatchEnd - เพิ่มเหตุการณ์

    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")
  2. เหนือ respawnPlayerInLobby() เพิ่มฟังก์ชันใหม่ท้องถิ่นที่มีชื่อว่า checkPlayerCount()


    -- แปรผู้เล่น
    local activePlayers = {}
    local playerWeapon = ServerStorage.Weapon
    local function checkPlayerCount()
    end
    local function respawnPlayerInLobby(player)
  3. ในส่วนนั้นใช้ประโยค if เพื่อตรวจสอบผู้ชนะ ในประโยคนั้น:

    • ตรวจสอบว่าขนาดของตาราง activePlayers มีขนาด 1
    • หากเป็นเช่นนั้น, ยิง matchEnd และผ่านใน gameSettings.endStates.FoundWinner .

    local function checkPlayerCount()
    if #activePlayers == 1 then
    matchEnd:Fire(gameSettings.endStates.FoundWinner)
    end
    end

การลบผู้เล่น

การนับจำนวนที่แม่นยำไม่สามารถเก็บไว้ได้เว้นแต่ผู้เล่นถูกลบออก เมื่อผู้เล่นถูกเอาชนะออกจากโต๊ะผู้เล่น ให้เก็บจำนวนผู้เล่นที่แม่นยำโดยการลบพวกเขาออกจากโต๊ะผู้เล่น

  1. ภายใต้ checkPlayerCount() สร้างฟังก์ชันใหม่ที่มีชื่อว่า removeActivePlayer() ด้วยตัวอ้างอิงชื่อว่า player


    local function checkPlayerCount()
    if #activePlayers == 1 then
    matchEnd:Fire(gameSettings.endStates.FoundWinner)
    end
    end
    local function removeActivePlayer(player)
    end
  2. เพื่อค้นหาผู้เล่นในตาราง activePlayers ใช้วิธีการที่เรียบง่ายโดยใช้ for ลูป จากนั้นเพิ่มข้อความ if ที่วิ่งเมื่อผู้เล่นตรงกับชื่อพบใน ฟังก์ชัน


    local function removeActivePlayer(player)
    for playerKey, whichPlayer in activePlayers do
    if whichPlayer == player then
    end
    end
    end
  3. เพื่อลบผู้เล่นออกจาก if สถานะ:

    • โทร table.remove() ภายในเครื่องเชื่อมต่อ ผ่าน activePlayers ตารางที่จะมองใน, และ playerKey - ผู้เล่นที่จะลบออกจากตาราง.
    • ตั้งค่าค่าของวัตถุ playersLeft ให้เป็น #activePlayers
    • ตรวจสอบผู้เล่นที่ชนะด้วยการประเมินผล checkPlayerCount()

    local function removeActivePlayer(player)
    for playerKey, whichPlayer in activePlayers do
    if whichPlayer == player then
    table.remove(activePlayers, playerKey)
    playersLeft.Value = #activePlayers
    checkPlayerCount()
    end
    end
    end

การเชื่อมต่อเหตุการณ์และการทดสอบ

เพื่อใช้งานฟังก์ชันที่เพิ่งสร้างขึ้นโปรดเรียกมันจากภายในการโทรฟังก์ชันที่ปลอมที่เชื่อมต่อกับเหตุการณ์ Died ของผู้เล่น

  1. ค้นหา preparePlayer() ในระบบฟังก์ชันแบบไม่ระบุที่มีการเชื่อมต่อกับอีเวนต์ Died โทร removeActivePlayer() แล้วส่งผู้เล่นเป็นตัวแปร


    humanoid.Died:Connect(function()
    respawnPlayerInLobby(player)
    removeActivePlayer(player)
    end)
  2. เพื่อดูว่าผู้เล่นที่ชนะพบหรือไม่ เริ่มเซิร์ฟเวอร์ทดสอบ เดี่ยว เมื่อมีผู้เล่นเหลืออยู่เพียงคนเดียวคุณควรเห็น พบวิลเลียม ในหน้าต่างการออก

  3. ปิดหมายเหตุเมื่อการแข่งขันใหม่เริ่มขึ้นในหน้าต่างการออกมีข้อผิดพลาดปรากฏขึ้น:

ข้อผิดพลาดนี้เกิดขึ้นเพราะเวลาไม่หยุด ซึ่งจะแก้ไขในส่วนถัดไป

การหยุดนับเวลา

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

  1. ใน MatchManager สร้างคุณสมบัติใหม่ที่มีชื่อว่า stopTimer() ภายใน ใส่ myTimer:stop() เพื่อหยุดนาฬิกา


    -- สร้างวัตถุจับเวลาใหม่ที่จะใช้เพื่อติดตามเวลาการแข่งขัน
    local myTimer = timer.new()
    -- หน้าต่างท้องถิ่น
    local function stopTimer()
    myTimer:stop()
    end
    local function timeUp()
    matchEnd:Fire(gameSettings.endStates.TimerUp)
    end
  2. เพื่อหยุดนับเวลาเมื่อการแข่งขันจบลง, เชื่อมต่อเหตุการณ์สิ้นสุดการแข่งขันไปที่ stopTimer()


    -- หน้าโมดูล
    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    matchStart:Fire()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  3. ทดสอบ ว่าข้อผิดพลาดก่อนหน้านี้ไม่ปรากฏอีกต่อไปโดยการเริ่ม เซิร์ฟเวอร์ ใหม่ ลบข้อผิดพลาดทั้งหมด ยกเว้นผู้เล่นคนเดียวแล้วรอสองวินาทีหลังจากที่มันจบ

ขั้นตอนต่อไป

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

สคริปที่สำเร็จ

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

สคริปต์ 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)
end
end
local function removeActivePlayer(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 onPlayerJoin(player)
player.RespawnLocation = lobbySpawn
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
-- หน้าโมดูล
function PlayerManager.sendPlayersToMatch()
local arenaSpawns = spawnLocations:GetChildren()
for playerKey, whichPlayer in Players:GetPlayers() do
table.insert(activePlayers, whichPlayer)
local spawnLocation = table.remove(arenaSpawns, 1)
preparePlayer(whichPlayer, spawnLocation)
end
playersLeft.Value = #activePlayers
end
-- เหตุการณ์
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager

สคริปต์ GameSettings


local GameSettings = {}
-- แปรแกม
GameSettings.intermissionDuration = 5
GameSettings.matchDuration = 10
GameSettings.minimumPlayers = 2
GameSettings.transitionTime = 5
-- ปิด
GameSettings.endStates = {
TimerUp = "TimerUp",
FoundWinner = "FoundWinner"
}
return GameSettings

สคริปต์ 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()
print("Game ended with: " .. endState)
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 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()
print("Timer started")
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
matchStart.Event:Connect(startTimer)
matchEnd.Event:Connect(stopTimer)
return MatchManager