Pertandingan dapat berakhir dalam beberapa kondisi, termasuk timer yang habis atau pemain tunggal yang ditinggalkan.
Mengelola Pemain yang Kalah
Saat ini, pemain yang dikalahkan muncul kembali di arena. Sebaliknya, kirim mereka kembali ke lobi untuk menunggu mencocokkanberikutnya.
- Di PlayerManager, buat fungsi lokal bernama respawnPlayerInLobby() . Di fungsi itu, lakukan mengikuti:
- Tetapkan propinsi RespawnLocation pemain ke lobiSpawn.
- Reload karakter dengan Player:LoadCharacter() . Ingat, LoadCharacter() menggulir ulang pemain di spawn mereka, menghapus semua alat yang mereka miliki.
Menggunakan Fungsi Anonim
Fungsi anonim sering digunakan dalam skrip lanjutan di bawah situasi tertentu. Sebelum mendefinisikannya, penting untuk memahami situasi yang mungkin ditghadapi oleh skrip Anda.
Pertimbangkan ini: Untuk mengirim pemain yang dikalahkan ke lobi, fungsi respawn harus terhubung ke acara Died pemain. Ada masalah. Jika Anda menghubungkan acara seperti yang kami miliki di masa lalu, tidak ada cara untuk mendapatkan nama pemain dari acara Died. Skrip memerlukan nama itu untuk menghapus pemain yang dikalahkan dari tabel melacak pemain aktif.
Untuk mendapatkan nama pemain yang memicu acara Died, gunakan fungsi anonim. Fungsi anonim tidak memiliki nama, dan dapat dibuat secara langsung di Connect() daripada secara terpisah.
Sebuah fungsi anonim sampel di bawah ini yang menunjukkan syntax.
myPlayer.Died:Connect(function()
print(player)
end)
Mengkode Acara yang Mati
Untuk fungsi ini, setiap kali karakter pemain mati, mereka akan mengaktifkan fungsi yang menghasilkan ulang mereka.
Untuk mendapatkan akses ke acara Died pemain, di PlayerManager > preparePlayer() , tambahkan variabel untuk pemain's humanoid.
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 Died. Mulai dengan mengetik humanoid.Died:Connect() . Kemudian, di dalam Connect() , jenis 1> function()1> , tekan 4> Enter4> untuk menyelesaikan otomatisasi 7> akhiri7> , dan hapus tanda paret 9>
local humanoid = character:WaitForChild("Humanoid")humanoid.Died:Connect(function()end)Dalam fungsi anonim, panggil respawnPlayerInLobby() . Pass dalam player, variabel yang menyimpan pemain siap untuk memasuki mencocokkan.
local humanoid = character:WaitForChild("Humanoid")humanoid.Died:Connect(function()respawnPlayerInLobby(player)end)Mulai sebuah server dan mainkan mencocokkan. Tes bahwa ketika seorang pemain mati, mereka akan muncul kembali di lobi. Untuk mengalahkan pemain, berjalanlah ke mereka dan gunakan senjata Anda sampai Anda bisa mengkonfirmasi bahwa mereka telah muncul kembali di lobi.
Catat, ada juga beberapa cara pengujian yang berbeda jika diinginkan.
- Untuk membunuh pemain, di Jendela Keluar > Server > Bar Komando, salinan dan pasta: workspace.Player1.Humanoid.Health = 0 . Tekan Masukkan untuk mengeksekusi perintah. Untuk menghapus pemain lain, gunakan Player2, Player3, dll.
- Mengatur GameSettings > matchDuration ke waktu yang lebih lama dapat memberi Anda lebih banyak waktu untuk menemukan dan mengambil semua pemain.
- Untuk tes yang lebih cepat, ubah GameSettings > minimumPlayers menjadi nomor yang lebih kecil, seperti 2.
Menyelesaikan permainan
Sekarang bahwa pemain yang dikalahkan respawn, mulai bekerja pada menghabisi game. Ingat untuk menciptakan acara PertandinganAntara saat timer berakhir atau pemenang ditemukan.
Untuk mengatakan kepada para skrip lainnya bahwa kondisi tertentu telah mengakhiri game, buat tabel dengan variabel untuk TimerUp dan FoundWinner . Ketika acara pertandingan berakhir, itu akan diberikan dalam variabel sehingga skrip lainnya dapat merespon.
Pada GameSettings, buat tabel modul kosong bernama endStates .
local GameSettings = {}-- Variabel GameGameSettings.intermissionDuration = 5GameSettings.matchDuration = 10GameSettings.minimumPlayers = 2GameSettings.transitionTime = 5-- Kemungkinan cara permainan dapat akhiri.GameSettings.endStates = {}return GameSettingsBuat dua variabel bernama TimerUp dan FoundWinner . Setiap variabel ke satu string yang cocok dengan nama mereka. String ini akan digunakan untuk menguji kode.
GameSettings.endStates = {TimerUp = "TimerUp",FoundWinner = "FoundWinner"}
Berakhir dengan Timer
Ketika timer berakhir, fire the Match End event dan send the matching end state variable. Dengan cara ini, skrip lain yang mendengarkan untuk acara itu dapat merespon sesuai. Ingat bahwa ketika sinyal acara berakhir, itu juga dapat mengirimkan data yang diterima dengan mendengarkan skrip, seperti TimerUp atau FoundWinner .
Dalam GameManager , dalam sementara benar do 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 menghapus pernyataan cetak. Kemudian, untuk menjalankan acara akhir pertandingan, ketik matchEnd:Fire() dan masukkan 2> gameSettings.endSettings.TimerUp2> .
-- Nilailocal displayValues = ReplicatedStorage:WaitForChild("DisplayValues")local timeLeft = displayValues:WaitForChild("TimeLeft")-- Membuat objek timer baru untuk digunakan untuk melacak waktu pertandingan.local myTimer = timer.new()-- Fungsi Lokallocal function timeUp()matchEnd:Fire(gameSettings.endStates.TimerUp)endTes mencocokkan. Setelah waktu habis, periksa apakah pernyataan cetak mencakup string yang disimpan di variabel TimerUp.
Tips Troubleshoot
Pada saat ini, pesan tidak ditampilkan, coba salah satu dari berikut.
- Periksa bahwa di mana pun variabel akhir ditangani, bahwa mereka ditulis dengan benar, seperti di sini: gameSettings.endStates.TimerUp .
- Pastikan untuk menggunakan : (operator kolom) dengan Fire() alih-alih dari operator dot, seperti dalam matchEnd:Fire() .
Mengkode Pertandingan Menang
Selanjutnya, script perlu mengidentifikasi pemain yang menang, menghapus pemain yang kalah, dan menjalankan pembersihan seperti menghentikan timer. Pertandingan juga akan berakhir jika satu pemain tersisa. Untuk melihat apakah kondisi FoundWinner terpenuhi, Anda akan memerlukan fungsi yang memeriksa nomor tersisa di tabel melacak pemain dalam mencocokkan.
Menghitung Jumlah Pemain
Pertandingan akan berakhir jika hanya satu pemain tersisa. Untuk memeriksa ini, script perlu melacak pemain di putaran. Setelah satu pemain tersisa, pemenang dapat ditetapkan.
Dalam PlayerManager, definisikan variabel berikut:
- folder ModulScripts
- GameSettings module - Digunakan untuk mengakses variabel status akhir
- Event Folder dan acara Pertandingan - 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"))-- Acaralocal 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 if then statement untuk memeriksa pemenang. Dalam pernyataan itu:
- Periksa apakah ukuran tabel activePlayers adalah 1.
- Jika demikian, fire matchEnd dan pass in gameSettings.endStates.FoundWinner .
local function checkPlayerCount()if #activePlayers == 1 thenmatchEnd:Fire(gameSettings.endStates.FoundWinner)endend
Menghapus Pemain
Menghitung dengan tepat tidak dapat dilakukan kecuali pemain dihapus. Saat pemain dikalahkan, menyimpan menghitung dengan tepat pemain dengan menghapus mereka 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, ikuti tabel dengan menggunakan siklus for . Kemudian, tambahkan pernyataan if yang menjalankan jika pemain yang cocok dengan nama berhasil masuk ke fungsi.
local function removeActivePlayer(player)for playerKey, whichPlayer in activePlayers doif whichPlayer == player thenendendendUntuk menghapus pemain, dalam pernyataan if:
- Panggil table.remove() . Di dalam huruf, pas dalam activePlayers , tabel untuk melihat, dan playerKey - pemain untuk menghapus dari tabel.
- Tetapkan nilai objek playersLeft ke #activePlayers .
- Periksa pemain yang menang dengan mengeksekusi checkPlayerCount() .
local function removeActivePlayer(player)for playerKey, whichPlayer in activePlayers doif whichPlayer == player thentable.remove(activePlayers, playerKey)playersLeft.Value = #activePlayerscheckPlayerCount()endendend
Menghubungkan Acara dan Pengujian
Untuk menggunakan fungsi baru yang baru saja dibuat, panggil fungsi anonim yang terhubung ke acara Died pemain.
Temukan preparePlayer() . Dalam fungsi anonim dengan koneksi acara Died, panggil removeActivePlayer() . Kemudian, pas dalam pemain sebagai parameter.
humanoid.Died:Connect(function()respawnPlayerInLobby(player)removeActivePlayer(player)end)Untuk melihat apakah pemain yang menang ditemukan, mulai server pengujian . Ketika hanya ada satu pemain tersisa, Anda harus melihat FoundWinner di jendela keluaran.
Lanjutkan pengujian dan biarkan pertandingan akhiri. Perhatikan saat pertandingan baru dimulai, kesalahan muncul di Jendela Keluar:
Kesalahan ini karena timer tidak dihentikan, yang akan diperbaiki dalam bagian berikutnya.
Menghentikan Timer
Setiap kali pertandingan berakhir dengan pemain yang menang, timer harus berhenti juga. Untuk menghentikan timer saat waktu habis, tunggu timer saat pertandingan berakhir. Ini adalah salah satu manfaat dari membuat acara. Mereka dapat digunakan kembali dalam banyak situasi untuk menghentikan skrip penyebab dan efek.
Di MatchManager, buat fungsi lokal baru bernama stopTimer() . Di dalam, ketik myTimer:stop() untuk menghentikan timer.
-- Membuat objek timer 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 timer saat pertandingan berakhir, hubungkan acara pertandingan berakhir ke stopTimer() .
-- Fungsi Modulfunction MatchManager.prepareGame()playerManager.sendPlayersToMatch()matchStart:Fire()endmatchStart.Event:Connect(startTimer)matchEnd.Event:Connect(stopTimer)return MatchManagerUji bahwa kesalahan sebelumnya tidak lagi muncul dengan memulai server . Eliminasikan semua kecuali satu pemain dan kemudian tunggu beberapa detik setelah pertandingan berakhir.
Langkah Berikutnya
Sementara dua kondisi kemenangan selesai, masih ada beberapa tugas yang tersisa untuk menyelesaikan game loop. kejadian, pemain yang menang tidak pernah diteleportasi ke lobi. Pada lekcion berikutnya, Anda akan menunjukkan cara pertandingan berakhir ke pemain dan mengatur ulang permainan, akhirnya menyelesaikan seluruh loop.
Skrip yang Diselesaikan
Di bawah ini adalah script yang selesai untuk memeriksa kembali 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"))
-- Acara
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
-- Acara
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager
Skrip GameSettings
local GameSettings = {}-- Variabel GameGameSettings.intermissionDuration = 5GameSettings.matchDuration = 10GameSettings.minimumPlayers = 2GameSettings.transitionTime = 5-- Kemungkinan cara permainan dapat akhiri.GameSettings.endStates = {TimerUp = "TimerUp",FoundWinner = "FoundWinner"}return GameSettings
Skrip GameManager
-- 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"))-- Acaralocal 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 MatchManager
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"))
-- Acara
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 timer 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 pada 1 bukan 0.
timeLeft.Value = (math.floor(myTimer:getTimeLeft() + 1))
-- Dengan tidak menetapkan waktu tunggu, itu menawarkan lebih banyak looping yang 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