Pertandingan akhir

*Konten ini diterjemahkan menggunakan AI (Beta) dan mungkin mengandung kesalahan. Untuk melihat halaman ini dalam bahasa Inggris, klik di sini.

Pertandingan dapat berakhir dalam beberapa kondisi termasuk timer habis atau pemain tunggal ditinggalkan.

Manajemen pemain dikalahkan

Saat ini, pemain yang dikalahkan respawn di arena. Sebaliknya, kirim mereka kembali ke lobi untuk menunggu mencocokkanberikutnya.

  1. Di PlayerManager, buat fungsi lokal bernama respawnPlayerInLobby() . Dalam fungsi itu, lakukan hal mengikuti:
  • Tetapkan properti RespawnLocation pemain ke lobbySpawn.
  • Muat ulang karakter dengan Player:LoadCharacter() . Ingat, LoadCharacter() mereproduksi pemain di spawn mereka, menghapus alat apa pun yang mereka miliki.

Gunakan fungsi anonim

Fungsi anonim umumnya digunakan dalam skrip canggih di bawah situasi tertentu.Sebelum mendefinisikan mereka, penting untuk memahami situasi yang mungkin dihadapi skrip Anda.

Pertimbangkan ini: Untuk menteleportasi pemain yang dikalahkan ke lobi, fungsi respawn harus terhubung ke acara Meninggal pemain.Namun ada masalah.Jika Anda menghubungkan acara seperti yang kami miliki di masa lalu, tidak ada cara untuk mendapatkan nama pemain dari acara Meninggal.Skrip membutuhkan nama itu untuk menghapus pemain yang dikalahkan dari tabel pelacakan pemain aktif.

Untuk mendapatkan nama pemain yang memicu peristiwa Meninggal, gunakan fungsi anonim. Fungsi anonim tidak memiliki nama, dan dapat dibuat langsung dalam Connect() daripada terpisah.

Fungsi anonim sampel ada di bawah ini yang menunjukkan syntax.


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

Kode peristiwa mati

Untuk fungsi ini, setiap kali karakter pemain meninggal, mereka akan memicu fungsi yang menghidupkan kembali mereka.

  1. Untuk mendapatkan akses ke acara Meninggal pemain, di PlayerManager > preparePlayer() , tambahkan variabel untuk humanoid pemain.


    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. Buat fungsi anonim yang terhubung ke acara Meninggal.Mulai dengan mengetik humanoid.Died:Connect() .Kemudian, di dalam Connect() , ketik function() , tekan Enter untuk menyelesaikan secara otomatis end , dan hapus tanda kurung tambahan.


    local humanoid = character:WaitForChild("Humanoid")
    humanoid.Died:Connect(function()
    end)
  3. Dalam fungsi anonim, panggil respawnPlayerInLobby(). Berikan di player , variabel yang menyimpan pemain siap untuk masuk ke mencocokkan.


    local humanoid = character:WaitForChild("Humanoid")
    humanoid.Died:Connect(function()
    respawnPlayerInLobby(player)
    end)
  4. Mulai server dan mainkan mencocokkan.Uji ketika seorang pemain meninggal, mereka muncul kembali di lobi.Untuk mengalahkan pemain, berjalanlah ke mereka dan gunakan senjata Anda sampai Anda dapat mengkonfirmasi bahwa mereka telah respawn di lobi.

    Menyerang Pemain2
    Pemain2 di Lobi setelah respawning

Catatan, ada juga beberapa cara berbeda untuk menguji jika diinginkan.

  • Untuk membunuh pemain, di jendela Server > Output > Bar Perintah, salin dan tempel: workspace.Player1.Humanoid.Health = 0 .Tekan Enter untuk menjalankan perintah.Untuk menghapus pemain lain, gunakan Player2, Player3, dll.
  • Mengatur GameSettings > matchDuration untuk waktu yang lebih lama dapat memberi Anda lebih banyak waktu untuk menemukan dan mengeluarkan semua pemain.
  • Untuk melakukan tes lebih cepat, ubah GameSettings > minimumPlayers ke angka yang lebih kecil, seperti 2.

Akhiri game

Sekarang pemain yang dikalahkan itu respawn, mulai bekerja untuk mengakhiri game.Ingat menciptakan acara MatchEnd? Ini akan ditembak ketika timer habis atau pemenang ditemukan.

Untuk memberi tahu skrip lain yang kondisi mengakhiri game, buat tabel dengan variabel untuk TimerUp dan FoundWinner .Ketika acara akhir pertandingan terjadi, itu akan lewat dalam variabel sehingga skrip lain dapat menanggapi.

  1. Di GameSettings, buat tabel modul kosong bernama endStates .


    local GameSettings = {}
    -- Variabel Permainan
    GameSettings.intermissionDuration = 5
    GameSettings.matchDuration = 10
    GameSettings.minimumPlayers = 2
    GameSettings.transitionTime = 5
    -- Kemungkinan cara permainan bisa akhiri.
    GameSettings.endStates = {
    }
    return GameSettings
  2. Buat dua variabel bernama TimerUp dan FoundWinner . Setiap ke string yang cocok dengan nama mereka. String ini akan digunakan untuk menguji kode.


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

Selesai dengan pengatur waktu

Saat timer berakhir, nyalakan acara Akhir Pertandingan dan kirim variabel status akhir yang cocok.Dengan begitu, skrip lain yang mendengarkan acara tersebut dapat merespon sesuai.Ingat bahwa saat acara menyala sinyal, itu juga dapat mengirim data yang diterima oleh skrip pendengaran, seperti TimerUp atau FoundWinner.

  1. Di GameManager , dalam sementara true melakukan loop, temukan baris matchEnd.Event:Wait() . Pada awal baris, tambahkan 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. Untuk mengkonfirmasi bahwa status yang benar diterima, tambahkan pernyataan cetak termasuk 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. Di MatchManager, temukan timeUp() dan hapus pernyataan cetak.Kemudian, untuk menembak acara akhir pertandingan, ketik matchEnd:Fire() dan lewati gameSettings.endStates.TimerUp .


    -- Nilai
    local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
    local timeLeft = displayValues:WaitForChild("TimeLeft")
    -- Membuat objek penghitung waktu baru untuk digunakan untuk melacak waktu pertandingan.
    local myTimer = timer.new()
    -- Fungsi Lokal
    local function timeUp()
    matchEnd:Fire(gameSettings.endStates.TimerUp)
    end
  4. Tes mencocokkan. Setelah timer habis, periksa apakah pernyataan cetak termasuk string yang disimpan di variabel TimerUp.

Tip pemecahan masalah

Pada titik ini, pesan tidak ditampilkan, coba salah satu dari berikut ini.

  • Periksa bahwa di mana pun variabel negara akhir dipanggil, bahwa mereka ditulis persis, seperti di sini: gameSettings.endStates.TimerUp .
  • Pastikan untuk menggunakan: (operator kolon) dengan Fire() sebagai gantinya dari operator dot, seperti di matchEnd:Fire() .

Kode mencocokkanpemenang

Selanjutnya, skrip perlu mengidentifikasi pemain pemenang, menghapus pemain kalah, dan menjalankan pembersihan seperti menghentikan timer.Pertandingan juga akan berakhir jika satu pemain tersisa.Untuk melihat apakah kondisi FoundWinner terpenuhi, Anda akan membutuhkan fungsi yang memeriksa nomor yang tersisa di tabel pelacak pemain dalam mencocokkan.

Periksa jumlah pemain

Pertandingan akan berakhir jika hanya ada satu pemain tersisa.Untuk memeriksa ini, skrip perlu melacak pemain dalam satu ronde.Setelah satu pemain ditinggalkan, pemenang dapat ditugaskan.

  1. Di PlayerManager, definisikan variabel berikut:

    • Folder ModuleScripts
    • Modul GameSettings - Digunakan untuk mengakses variabel status akhir
    • Folder acara dan acara MatchEnd - Acara Kebakaran

    local PlayerManager = {}
    -- Layanan
    local Players = game:GetService("Players")
    local ServerStorage = game:GetService("ServerStorage")
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    -- Modul
    local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
    local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
    -- Peristiwa
    local events = ServerStorage:WaitForChild("Events")
    local matchEnd = events:WaitForChild("MatchEnd")
  2. Di atas respawnPlayerInLobby() , tambahkan fungsi lokal baru bernama checkPlayerCount() .


    -- Variabel Pemain
    local activePlayers = {}
    local playerWeapon = ServerStorage.Weapon
    local function checkPlayerCount()
    end
    local function respawnPlayerInLobby(player)
  3. Dalam fungsi itu, gunakan pernyataan if kemudian untuk memeriksa pemenang. Dalam pernyataan itu:

    • Periksa apakah ukuran tabel activePlayers adalah 1.
    • Jika demikian, tembak matchEnd dan lewati gameSettings.endStates.FoundWinner .

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

Hapus pemain

Hitungan akurat tidak dapat disimpan kecuali pemain dihapus.Ketika pemain dikalahkan, pertahankan hitungan pemain yang akurat dengan menghapusnya dari tabel pemain.Kemudian, periksa ukuran tabel pemain aktif untuk melihat apakah ada pemenang.

  1. Di bawah checkPlayerCount() , buat fungsi lokal baru bernama removeActivePlayer() dengan parameter bernama player .


    local function checkPlayerCount()
    if #activePlayers == 1 then
    matchEnd:Fire(gameSettings.endStates.FoundWinner)
    end
    end
    local function removeActivePlayer(player)
    end
  2. Untuk menemukan pemain di tabel activePlayers, ulangi melalui itu menggunakan loop for.Kemudian, tambahkan pernyataan if yang dijalankan jika pemain yang sesuai dengan nama masuk ke fungsi ditemukan.


    local function removeActivePlayer(player)
    for playerKey, whichPlayer in activePlayers do
    if whichPlayer == player then
    end
    end
    end
  3. Untuk menghapus pemain, dalam pernyataan if:

    • Panggil table.remove() . Di dalam kurungan, berikan activePlayers , tabel untuk dilihat, dan playerKey - pemain untuk dihapus dari tabel.
    • Tetapkan nilai objek playersLeft ke #activePlayers.
    • Periksa pemain pemenang dengan menjalankan 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

Hubungkan peristiwa dan uji coba

Untuk menggunakan fungsi baru saja dibuat, panggil dari dalam fungsi anonim yang terhubung ke acara Died pemain.

  1. Temukan preparePlayer() . Dalam fungsi anonim dengan koneksi acara Meninggal, panggil removeActivePlayer() . Kemudian, berikan pemain sebagai parameter.


    humanoid.Died:Connect(function()
    respawnPlayerInLobby(player)
    removeActivePlayer(player)
    end)
  2. Untuk melihat apakah pemain pemenang ditemukan, mulai server uji tes .Ketika hanya ada satu pemain yang tersisa, Anda harus melihat FoundWinner di jendela Output.

  3. Lanjutkan pengujian dan biarkan pertandingan akhiri. Perhatikan saat pertandingan baru dimulai, kesalahan muncul di jendela Output:

Kesalahan ini terjadi karena timer tidak dihentikan, yang akan diperbaiki di bagian berikutnya.

Hentikan timer

Kapan pun pertandingan berakhir dengan pemain pemenang, waktu harus berhenti juga.Untuk menghentikan waktu pada saat timer berakhir, memiliki timer berhenti setiap kali peristiwa akhir pertandingan terjadi.Ini adalah salah satu manfaat dari menciptakan acara.Mereka dapat digunakan kembali dalam banyak situasi untuk menulis hubungan penyebab dan efek skrip.

  1. Di MatchManager, buat fungsi lokal baru bernama stopTimer() . Di dalam, ketik myTimer:stop() untuk menghentikan timer.


    -- Membuat objek penghitung waktu baru untuk digunakan untuk melacak waktu pertandingan.
    local myTimer = timer.new()
    -- Fungsi Lokal
    local function stopTimer()
    myTimer:stop()
    end
    local function timeUp()
    matchEnd:Fire(gameSettings.endStates.TimerUp)
    end
  2. Untuk menghentikan waktu ketika pertandingan berakhir, hubungkan acara matchEnd ke stopTimer().


    -- Fungsi Modul
    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    matchStart:Fire()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  3. Tes bahwa kesalahan sebelumnya tidak lagi muncul dengan memulai server .Hilangkan semua tetapi satu pemain dan kemudian tunggu beberapa detik setelah pertandingan berakhir.

Langkah selanjutnya

Sementara dua kondisi menang selesai, masih ada beberapa tugas yang tersisa untuk menyelesaikan loop permainan.Sebagai kejadian, pemain pemenang tidak pernah dipindahkan ke lobi.Dalam pelajaran berikutnya, Anda akan menampilkan bagaimana pertandingan berakhir kepada pemain dan mengatur ulang game, akhirnya menyelesaikan seluruh loop.

Skrip selesai

Di bawah ini adalah skrip yang selesai untuk memeriksa ulang pekerjaan Anda.

Skrip Manajer Pemain


local PlayerManager = {}
-- Layanan
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Modul
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- Peristiwa
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
-- Variabel Peta
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- Nilai
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
-- Variabel Pemain
local activePlayers = {}
local playerWeapon = ServerStorage.Weapon
-- Fungsi Lokal
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
-- Fungsi Modul
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
-- Peristiwa
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager

Skrip Pengaturan Game


local GameSettings = {}
-- Variabel Permainan
GameSettings.intermissionDuration = 5
GameSettings.matchDuration = 10
GameSettings.minimumPlayers = 2
GameSettings.transitionTime = 5
-- Kemungkinan cara permainan bisa akhiri.
GameSettings.endStates = {
TimerUp = "TimerUp",
FoundWinner = "FoundWinner"
}
return GameSettings

Skrip Manajer Game


-- Layanan
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Skrip Modul
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
-- Peristiwa
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

Skrip Manajer Pertandingan


local MatchManager = {}
-- Layanan
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Skrip Modul
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local timer = require(moduleScripts:WaitForChild("Timer"))
-- Peristiwa
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- Nilai
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- Membuat objek penghitung waktu baru untuk digunakan untuk melacak waktu pertandingan.
local myTimer = timer.new()
-- Fungsi Lokal
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
-- Menambahkan +1 memastikan tampilan timer berakhir di 1 bukan 0.
timeLeft.Value = (myTimer:getTimeLeft() + 1) // 1
-- Dengan tidak menetapkan waktu untuk menunggu, ia menawarkan looping yang lebih akurat
task.wait()
end
end
-- Fungsi Modul
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
matchStart.Event:Connect(startTimer)
matchEnd.Event:Connect(stopTimer)
return MatchManager