Maçları bitirme

*Bu içerik, yapay zekâ (beta) kullanılarak çevrildi ve hatalar içerebilir. Sayfayı İngilizce görüntülemek için buraya tıkla.

Maçlar, zamanlayıcıların tükenmesi veya tek bir oyuncunun kalması gibi birkaç koşulda sona erebilir.

Yenilmiş oyuncuları yönet

Şu anda, mağlup edilen oyuncular arenada yeniden doğuyor. Bunun yerine, bir sonraki eşleşmebeklemek için lobiye geri gönderin.

  1. PlayerManager'da, respawnPlayerInLobby() adlı yerel bir işlev oluşturun. Bu işlevde takip edilenyapın:
  • oyuncuyeniden doğma konumunu lobiSpawn'a ayarlayın.
  • Karakteri Player:LoadCharacter() ile yeniden yükle. Unutma, LoadCharacter() oyuncuyu doğdukları yerde yeniden yaratır ve sahip oldukları herhangi bir aleti kaldırır.

Anonim işlevleri kullan

Anonim işlevler, belirli durumlar altında gelişmiş senaryolarda yaygın olarak kullanılır.Onları tanımlamadan önce, senaryonuzun karşılaşabileceği bir durumu anlamak önemlidir.

Bunu düşünün: Mağlup oyuncuları lobiye ışıtmak için, yeniden doğma işlevinin oyuncunun Öldü etkinliğine bağlanması gerekecektir.Ancak bir sorun var.Etkinliği geçmişte olduğu gibi bağlarsanız, oyuncunun adını Died etkinliğinden almanın bir yolu yoktur.Senaryo, mağlup bir oyuncuyu aktif oyunları izleyen tablodan kaldırmak için bu isme ihtiyaç duyar.

Öldürme olayını tetikleyen oyuncunun adını almak için anonim bir işlev kullanın. Anonim işlevler adına sahip değildir ve ayrı olarak yerine doğrudan Connect() içinde oluşturulabilir.

Örnek anonim işlev, sözdizimini gösteren aşağıdadır.


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

Ölen olayı kodlayın

Bu işlev için, bir oyuncunun karakteri öldüğünde, onları yeniden doğuran işlevi tetikleyeceklerdir.

  1. Oyuncunun Öldü etkinliğine erişmek için, PlayerManager > preparePlayer() , oyuncunun insansız için bir değişken ekleyin.


    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 etkinliğine bağlanan anonim bir işlev oluşturun.humanoid.Died:Connect() yazarak başlayın.Sonra, içinde , yaz, otomatik tamamlanması için bas ve fazladan parantezleri sil.


    local humanoid = character:WaitForChild("Humanoid")
    humanoid.Died:Connect(function()
    end)
  3. Anonim işlevde, respawnPlayerInLobby() 'yi arayın. player , oyuncunun bir eşleşmegirmek üzere hazırlandığı depolayan bir değişken geçirin.


    local humanoid = character:WaitForChild("Humanoid")
    humanoid.Died:Connect(function()
    respawnPlayerInLobby(player)
    end)
  4. Bir sunucu başlat ve bir eşleşmeoyna.Bir oyuncu öldüğünde, lobide yeniden doğduklarını test edin.Oyuncuları yenmek için, onlara doğru yürüyün ve lobide yeniden doğduklarını onaylayana kadar silahınızı kullanın.

    Oyuncu2'ye Saldırma
    Oyuncu2, yeniden doğduktan sonra lobide

Not, istenirse test etmenin de farklı yolları vardır.

  • Bir oyuncuyu öldürmek için, Sunucu > Çıktı penceresi > Komut çubuğunda kopyala ve yapıştır: workspace.Player1.Humanoid.Health = 0 .Komutu çalıştırmak için Enter basın.Diğer oyuncuları kaldırmak için Player2, Player3 vb. kullanın
  • OyunSettings > matchDuration daha uzun bir süre ayarlamak, tüm oyuncuları bulmak ve çıkarmak için daha fazla zaman verebilir.
  • Daha hızlı testler yapmak için, GameSettings > minimumPlayers 'yi 2 gibi daha küçük bir sayıya değiştirin.

Oyunu oyun

Şimdi yenilmiş oyuncular yeniden doğdu, oyunu bitirmek için çalışmaya başla.MaçSonu etkinliğini oluşturmayı hatırlıyor musunuz? Zamanlayıcı tükendiğinde veya bir kazanan bulunduğunda ateşlenecek.

Diğer senaryolara hangi koşulun oyunu bitirdiğini söylemek için, TimerUp ve FoundWinner için değişkenlerle bir tablo oluşturun.Maç bitim etkinliği ateşlendiğinde, diğer kodların yanıt verebilmesi için bir değişken olarak geçecektir.

  1. GameSettings'te, boş bir modül tablosu olan endStates adlı boş bir tablo oluşturun.


    local GameSettings = {}
    -- Oyun Değişkenleri
    GameSettings.intermissionDuration = 5
    GameSettings.matchDuration = 10
    GameSettings.minimumPlayers = 2
    GameSettings.transitionTime = 5
    -- Oyunun bitirolası yolları.
    GameSettings.endStates = {
    }
    return GameSettings
  2. TimerUp ve FoundWinner adlı iki değişken oluşturun. Her birini adlarına uyan bir dizeye ayarlayın. Bu dizeler kodu test etmek için kullanılacaktır.


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

Bir zamanlayıcı ile bitir

Zamanlayıcı sona erdiğinde, Maç Sonu etkinliğini ateşleyin ve eşleşen son durum değişkenini gönderin.Bu şekilde, bu olayı dinleyen diğer kodlar da buna göre yanıt verebilir.Etkinliklerin sinyalleri ateşlerken, dinleme kriptleri tarafından alınan verileri de gönderebileceğini unutmayın, örneğin TimerUp veya FoundWinner.

  1. In GameManager , while true do döngüsünde, çizgi matchEnd.Event:Wait() bulun. Çizginin başında, local endState = ekleyin.


    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. Doğru durumun alındığını onaylamak için, endState içeren bir yazıcı ifadesi ekleyin.


    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'da, bulun ve baskı ifadesini kaldır.Sonra, maç bitim etkinliğini ateşlemek için matchEnd:Fire() yazın ve gameSettings.endStates.TimerUp geçirin.


    -- Değerler
    local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
    local timeLeft = displayValues:WaitForChild("TimeLeft")
    -- Maç süresini izlemek için kullanılacak yeni bir zamanlayıcı nesnesi oluşturur.
    local myTimer = timer.new()
    -- Yerel Fonksiyonlar
    local function timeUp()
    matchEnd:Fire(gameSettings.endStates.TimerUp)
    end
  4. Bir eşleşmeyi test edin. Zamanlayıcı tükendikten sonra, yazıcı ifadesinin TimerUp değişkenine depolanan dizeyi içerdiğinden emin olun.

Sorun giderme ipuçları

Bu noktada, mesaj görüntülenmedi, aşağıdan birini deneyin.

  • Son durum değişkenlerinin her yerde çağrıldığından emin olun, burada olduğu gibi kesinlikle yazıldılar: gameSettings.endStates.TimerUp .
  • Nokta operatörünün yerine nokta operatörünü kullanmak suretiyle :( virgül operatörü) ile çalıştığınızdan emin olun, örneğin .

Kazanan bir eşleşmekodla

Sonra, senaryonun kazanan oyuncuları tanımlaması, kaybeden oyuncuları kaldırması ve zamanlayıcıyı durdurma gibi temizlik yapması gerekir.Maçlar ayrıca bir oyuncu kaldığında da sona erecek.FoundWinner koşulunun yerine getirildiğini görmek için, bir eşleşmeoyuncuları izleyen tabloda kalan sayıyı kontrol eden bir işleve ihtiyacınız olacak.

Oyuncu sayısını kontrol et

Maçlar, sadece bir oyuncu kaldığında sona erecek.Bunu kontrol etmek için, senaryo bir turda oyuncuları izlemelidir.Bir oyuncu kaldığında, bir kazanan atanabilir.

  1. Oyun Yöneticisinde, aşağıdaki değişkenleri tanımlayın:

    • ModülScripts klasörü
    • OyunAyarları modülü - Son durum değişkenlerine erişmek için kullanılır
    • Etkinlik klasörü ve MaçSonu etkinliği - Ateş etkinliği

    local PlayerManager = {}
    -- Hizmetler
    local Players = game:GetService("Players")
    local ServerStorage = game:GetService("ServerStorage")
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    -- Modüller
    local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
    local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
    -- Etkinlikler
    local events = ServerStorage:WaitForChild("Events")
    local matchEnd = events:WaitForChild("MatchEnd")
  2. Üstünde respawnPlayerInLobby() , yeni bir yerel işlev adında checkPlayerCount() ekleyin.


    -- Oyuncu Değişkenleri
    local activePlayers = {}
    local playerWeapon = ServerStorage.Weapon
    local function checkPlayerCount()
    end
    local function respawnPlayerInLobby(player)
  3. Bu işlev içinde, bir kazanan kontrol etmek için bir if then ifadesi kullanın. Bu ifade içinde:

    • activePlayers tablosunun boyutunun 1 olup olmadığını kontrol edin.
    • Eğer öyleyse, ateş et matchEnd ve geç gameSettings.endStates.FoundWinner .

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

Bir oyuncuyu kaldır

Oyuncular kaldırılana kadar doğru bir sayı tutulamaz.Bir oyuncu yenildiğinde, oyuncuları oyuncu tablosundan kaldırarak doğru bir oyuncu sayısı tutun.Sonra, aktif oyuncu tablosunun boyutunu kontrol ederek bir kazanan olup olmadığını görün.

  1. altında, adlı yeni yerel bir işlev oluşturun ve bir parametre ile adlandırılmış .


    local function checkPlayerCount()
    if #activePlayers == 1 then
    matchEnd:Fire(gameSettings.endStates.FoundWinner)
    end
    end
    local function removeActivePlayer(player)
    end
  2. Oyuncuyu activePlayers tablosunda bulmak için, bir for döngüsü kullanarak onun üzerinden dolaşın.Sonra, isimle eşleşen bir oyuncu fonksiyona geçtiğinde çalışan bir if ifadesi ekleyin.


    local function removeActivePlayer(player)
    for playerKey, whichPlayer in activePlayers do
    if whichPlayer == player then
    end
    end
    end
  3. oyuncukaldırmak için, if ifadesinde:

    • Ara table.remove() . Eşzamanlama içinde, activePlayers , bakmak için tabloyu geç ve playerKey - tableden kaldırmak için oyuncu.
    • playersLeft nesnesinin değerini #activePlayers olarak ayarlayın.
    • checkPlayerCount() koşarak kazanan bir oyuncu kontrol edin.

    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

Etkinlikleri ve testi bağla

Az önce oluşturulan işlevi kullanmak için, oyuncunun Died etkinliğine bağlı olan anonim işlevden çağırın.

  1. Bul preparePlayer() . Died etkinliği bağlantısıyla anonim işlevde, çağır removeActivePlayer() . Sonra, oyuncuyu parametre olarak geçir.


    humanoid.Died:Connect(function()
    respawnPlayerInLobby(player)
    removeActivePlayer(player)
    end)
  2. Kazanan bir oyuncu bulunup bulunmadığını görmek için, bir test sunucusu başlatın.Sadece bir oyuncu kaldığında Çıktı penceresinde FoundWinner'ı görmelisiniz.

  3. Testi sürdür ve maçın bitirizin ver. Yeni bir maç başladığında Çıktı penceresinde bir hata görünür:

Bu hata, zamanlayıcının durdurulmadığı için, bunun bir sonraki bölümde düzeltileceği.

Saati durdur

Bir maç kazanan bir oyuncu ile sona erdiğinde, zamanlayıcı da durmalıdır.Süre dolmadan önce zamanlayıcıyı durdurmak için, maç bitiş etkinliği herhangi bir zamanda durdurulduğunda zamanlayıcı durdurun.Bu, etkinlikler oluşturmanın avantajlarından biridir.Senaryo nedeni ve etkisi ilişkilerini yazmak için çok sayıda durumda yeniden kullanılabilirler.

  1. Maç Yöneticisinde, yeni bir yerel işlev oluştur stopTimer() . İçeri, zamanlayıcıyı durdurmak için myTimer:stop() yaz.


    -- Maç süresini izlemek için kullanılacak yeni bir zamanlayıcı nesnesi oluşturur.
    local myTimer = timer.new()
    -- Yerel Fonksiyonlar
    local function stopTimer()
    myTimer:stop()
    end
    local function timeUp()
    matchEnd:Fire(gameSettings.endStates.TimerUp)
    end
  2. Maç bitince zamanlayıcıyı durdurmak için, maç biti etkinliğini stopTimer() 'ye bağlayın.


    -- Modül İşlevleri
    function MatchManager.prepareGame()
    playerManager.sendPlayersToMatch()
    matchStart:Fire()
    end
    matchStart.Event:Connect(startTimer)
    matchEnd.Event:Connect(stopTimer)
    return MatchManager
  3. Test önceki hata artık bir sunucu başlatarak görünmediğini kontrol et.Tek oyuncu hariç hepsini ortadan kaldır ve ardından maç bitince birkaç saniye bekleyin.

Sonraki adımlar

İki kazanma koşulu bitmiş olsa da, oyun döngüsünü bitirmek için hala bazı görevler kaldı.durum, kazanan oyuncu asla lobiye ışınlanmaz.Bir sonraki ders, maçın oyunculara nasıl son verdiğini gösterip oyunu sıfırlayacak ve sonunda tüm döngüyü bitireceksiniz.

Tamamlanmış senaryolar

Aşağıda, çalışmanızı kontrol etmek için bitmiş senaryolar bulunmaktadır.

Oyuncu Yöneticisi senaryosu


local PlayerManager = {}
-- Hizmetler
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Modüller
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
-- Etkinlikler
local events = ServerStorage:WaitForChild("Events")
local matchEnd = events:WaitForChild("MatchEnd")
-- Harita Değişkenleri
local lobbySpawn = workspace.Lobby.StartSpawn
local arenaMap = workspace.Arena
local spawnLocations = arenaMap.SpawnLocations
-- Değerler
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local playersLeft = displayValues:WaitForChild("PlayersLeft")
-- Oyuncu Değişkenleri
local activePlayers = {}
local playerWeapon = ServerStorage.Weapon
-- Yerel Fonksiyonlar
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
-- Modül İşlevleri
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
-- Etkinlikler
Players.PlayerAdded:Connect(onPlayerJoin)
return PlayerManager

OyunAyarları scripti


local GameSettings = {}
-- Oyun Değişkenleri
GameSettings.intermissionDuration = 5
GameSettings.matchDuration = 10
GameSettings.minimumPlayers = 2
GameSettings.transitionTime = 5
-- Oyunun bitirolası yolları.
GameSettings.endStates = {
TimerUp = "TimerUp",
FoundWinner = "FoundWinner"
}
return GameSettings

GameManager senaryosu


-- Hizmetler
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
-- Modül Kodları
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local matchManager = require(moduleScripts:WaitForChild("MatchManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local displayManager = require(moduleScripts:WaitForChild("DisplayManager"))
-- Etkinlikler
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

MaçYöneticisi skripti


local MatchManager = {}
-- Hizmetler
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Modül Kodları
local moduleScripts = ServerStorage:WaitForChild("ModuleScripts")
local playerManager = require(moduleScripts:WaitForChild("PlayerManager"))
local gameSettings = require(moduleScripts:WaitForChild("GameSettings"))
local timer = require(moduleScripts:WaitForChild("Timer"))
-- Etkinlikler
local events = ServerStorage:WaitForChild("Events")
local matchStart = events:WaitForChild("MatchStart")
local matchEnd = events:WaitForChild("MatchEnd")
-- Değerler
local displayValues = ReplicatedStorage:WaitForChild("DisplayValues")
local timeLeft = displayValues:WaitForChild("TimeLeft")
-- Maç süresini izlemek için kullanılacak yeni bir zamanlayıcı nesnesi oluşturur.
local myTimer = timer.new()
-- Yerel Fonksiyonlar
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 eklemek, zamanlayıcının 0 yerine 1'de sona ermesini sağlar.
timeLeft.Value = (myTimer:getTimeLeft() + 1) // 1
-- Bekleme süresini ayarlamayarak, daha doğru döngüleme sağlar
task.wait()
end
end
-- Modül İşlevleri
function MatchManager.prepareGame()
playerManager.sendPlayersToMatch()
matchStart:Fire()
end
matchStart.Event:Connect(startTimer)
matchEnd.Event:Connect(stopTimer)
return MatchManager