Mengakhiri Pertandingan

*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 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.

  1. 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.

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


    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 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)
  3. 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)
  4. 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.

    Menyerang Pemain2
    Pemain2 di Lobi setelah respawning

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.

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


    local GameSettings = {}
    -- Variabel Game
    GameSettings.intermissionDuration = 5
    GameSettings.matchDuration = 10
    GameSettings.minimumPlayers = 2
    GameSettings.transitionTime = 5
    -- Kemungkinan cara permainan dapat akhiri.
    GameSettings.endStates = {
    }
    return GameSettings
  2. Buat 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 .

  1. Dalam GameManager , dalam sementara benar do 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 menghapus pernyataan cetak. Kemudian, untuk menjalankan acara akhir pertandingan, ketik matchEnd:Fire() dan masukkan 2> gameSettings.endSettings.TimerUp2> .


    -- 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 timeUp()
    matchEnd:Fire(gameSettings.endStates.TimerUp)
    end
  4. Tes 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.

  1. Dalam PlayerManager, definisikan variabel berikut:

    • folder ModulScripts
    • GameSettings module - Digunakan untuk mengakses variabel status akhir
    • Event Folder dan acara Pertandingan - 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"))
    -- Acara
    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 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 then
    matchEnd:Fire(gameSettings.endStates.FoundWinner)
    end
    end

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.

  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, 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 do
    if whichPlayer == player then
    end
    end
    end
  3. Untuk 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 do
    if whichPlayer == player then
    table.remove(activePlayers, playerKey)
    playersLeft.Value = #activePlayers
    checkPlayerCount()
    end
    end
    end

Menghubungkan Acara dan Pengujian

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

  1. 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)
  2. Untuk melihat apakah pemain yang menang ditemukan, mulai server pengujian . Ketika hanya ada satu pemain tersisa, Anda harus melihat FoundWinner di jendela keluaran.

  3. 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.

  1. 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 Lokal
    local function stopTimer()
    myTimer:stop()
    end
    local function timeUp()
    matchEnd:Fire(gameSettings.endStates.TimerUp)
    end
  2. Untuk menghentikan timer saat pertandingan berakhir, hubungkan acara pertandingan berakhir ke stopTimer() .


    -- Fungsi Modul
    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    matchStart:Fire()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  3. Uji 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 Game
GameSettings.intermissionDuration = 5
GameSettings.matchDuration = 10
GameSettings.minimumPlayers = 2
GameSettings.transitionTime = 5
-- Kemungkinan cara permainan dapat akhiri.
GameSettings.endStates = {
TimerUp = "TimerUp",
FoundWinner = "FoundWinner"
}
return GameSettings

Skrip GameManager


-- 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"))
-- Acara
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 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