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.
- 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.
Untuk mendapatkan akses ke acara Meninggal pemain, di PlayerManager > preparePlayer() , tambahkan variabel untuk humanoid pemain.
local function preparePlayer(player, whichSpawn)player.RespawnLocation = whichSpawnplayer:LoadCharacter()local character = player.Character or player.CharacterAdded:Wait()local sword = playerWeapon:Clone()sword.Parent = characterlocal humanoid = character:WaitForChild("Humanoid")endBuat 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)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)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.
Di GameSettings, buat tabel modul kosong bernama endStates .
local GameSettings = {}-- Variabel PermainanGameSettings.intermissionDuration = 5GameSettings.matchDuration = 10GameSettings.minimumPlayers = 2GameSettings.transitionTime = 5-- Kemungkinan cara permainan bisa akhiri.GameSettings.endStates = {}return GameSettingsBuat 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.
Di GameManager , dalam sementara true melakukan loop, temukan baris matchEnd.Event:Wait() . Pada awal baris, tambahkan local 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()endUntuk mengkonfirmasi bahwa status yang benar diterima, tambahkan pernyataan cetak termasuk 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()print("Game ended with: " .. endState)endDi MatchManager, temukan timeUp() dan hapus pernyataan cetak.Kemudian, untuk menembak acara akhir pertandingan, ketik matchEnd:Fire() dan lewati gameSettings.endStates.TimerUp .
-- Nilailocal 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 Lokallocal function timeUp()matchEnd:Fire(gameSettings.endStates.TimerUp)endTes 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.
Di PlayerManager, definisikan variabel berikut:
- Folder ModuleScripts
- Modul GameSettings - Digunakan untuk mengakses variabel status akhir
- Folder acara dan acara MatchEnd - Acara Kebakaran
local PlayerManager = {}-- Layananlocal Players = game:GetService("Players")local ServerStorage = game:GetService("ServerStorage")local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Modullocal moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))-- Peristiwalocal events = ServerStorage:WaitForChild("Events")local matchEnd = events:WaitForChild("MatchEnd")Di atas respawnPlayerInLobby() , tambahkan fungsi lokal baru bernama checkPlayerCount() .
-- Variabel Pemainlocal activePlayers = {}local playerWeapon = ServerStorage.Weaponlocal function checkPlayerCount()endlocal function respawnPlayerInLobby(player)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 thenmatchEnd:Fire(gameSettings.endStates.FoundWinner)endend
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.
Di bawah checkPlayerCount() , buat fungsi lokal baru bernama removeActivePlayer() dengan parameter bernama player .
local function checkPlayerCount()if #activePlayers == 1 thenmatchEnd:Fire(gameSettings.endStates.FoundWinner)endendlocal function removeActivePlayer(player)endUntuk 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 doif whichPlayer == player thenendendendUntuk 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 doif whichPlayer == player thentable.remove(activePlayers, playerKey)playersLeft.Value = #activePlayerscheckPlayerCount()endendend
Hubungkan peristiwa dan uji coba
Untuk menggunakan fungsi baru saja dibuat, panggil dari dalam fungsi anonim yang terhubung ke acara Died pemain.
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)Untuk melihat apakah pemain pemenang ditemukan, mulai server uji tes .Ketika hanya ada satu pemain yang tersisa, Anda harus melihat FoundWinner di jendela Output.
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.
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 Lokallocal function stopTimer()myTimer:stop()endlocal function timeUp()matchEnd:Fire(gameSettings.endStates.TimerUp)endUntuk menghentikan waktu ketika pertandingan berakhir, hubungkan acara matchEnd ke stopTimer().
-- Fungsi Modulfunction MatchManager.prepareGame()playerManager.sendPlayersToMatch()matchStart:Fire()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerTes 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 PermainanGameSettings.intermissionDuration = 5GameSettings.matchDuration = 10GameSettings.minimumPlayers = 2GameSettings.transitionTime = 5-- Kemungkinan cara permainan bisa akhiri.GameSettings.endStates = {TimerUp = "TimerUp",FoundWinner = "FoundWinner"}return GameSettings
Skrip Manajer Game
-- Layananlocal ServerStorage = game:GetService("ServerStorage")local Players = game:GetService("Players")-- Skrip Modullocal moduleScripts = ServerStorage:WaitForChild("ModuleScripts")local matchManager = require(moduleScripts:WaitForChild("MatchManager"))local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))-- Peristiwalocal 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()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