Algoritmayı Anlama
Oyun başladığında her takımı uygun sayıda oyuncuya sahip olacak şekilde dengelememiz gerekir.
Oyuncu dengelemenin simetrik olduğu ve oyuncuların takımlar arasında eşit şekilde dağıtıldığı oyunların aksine, asimetrik takım dengeleme her takımın göreli bir oyuncu sayısına sahip olacağı anlamına gelir. Diğer bir deyişle takım boyutları göreli bir oranı takip etmelidir.
Örneğin, bir takımın her zaman diğerinden iki kat fazla oyuncuya sahip olmasını isteyebilirsin. Oyuncular katıldıkça bu göreli sayıyı koruyacak şekilde dengeleme yapman gerekir. Bir takımın daha güçlü olduğu veya diğer takımdan farklı becerilere sahip olduğu oyun modlarında asimetrik dengeleme, her takımdaki oyuncu sayılarını dikkatlice dağıtarak daha sorunsuz oyun deneyimleri oluşturur.
Bu örnekte, maksimum oyuncu sayısı daha fazla olan takımların (burada Savunmacılar), maksimum oyuncu sayısı daha düşük olan takımlardan (Casuslar gibi) her zaman daha fazla oyuncuya sahip olduğundan emin olman gerekir.
Oyuncuları doğru şekilde dağıtmak için her bir oyuncuyu, kendi maksimum oyuncu sayısından en uzakta olan takıma yerleştirmen gerekecektir.
Bunu yapmak için her yeni oyuncu için takımları tek tek kontrol etmen, bir takımdaki maksimum ve geçerli oyuncu sayısının yanı sıra bu oyuncunun atanacağı takımın referansını kaydetmen gerekir. Maksimum oyuncu sayısını mevcut oyuncu sayısından çıkararak maksimum sayı ile farkı elde edebilirsin. Maksimum sayısıyla farkı en büyük olan takım bulunduğunda oyuncuyu o takıma atanacak şekilde ayarlamalısın.
Her bir takım için yineleme yaparak en büyük farka sahip takımı bulduğundan emin olabilirsin.
Algoritmayı Tanımlama
Bu adım, bir oyunun başlangıcında oyuncu takımlarını nasıl asimetrik bir şekilde dengeleyeceğini gösterir.
triad_infiltration_game
sınıfınaBalanceTeams()
adlı yeni bir metot ekle. Bu metot, maksimum oyuncu sayısıyla en büyük farka sahip olan takıma bir oyuncu atar.# Tüm oyuncuları oyundaki tüm takımlar arasında dengeler BalanceTeams():void= Logger.Print("Takım dengeleme başlıyor")
- Oyundaki tüm oyuncuları al ve
AllPlayers
değişken dizisinde depola. Ardından,AllPlayers
listesini karıştır. Bunu yapmak, oyuncuların takımlara başlangıçta oyuna katıldıkları sırayla değil de rastgele atanmalarını sağlar.# Tüm oyuncuları oyundaki tüm takımlar arasında dengeler BalanceTeams():void= Logger.Print("Takım dengeleme başlıyor") var AllPlayers:[]player := GetPlayspace().GetPlayers() set AllPlayers = Shuffle(AllPlayers)
- Şimdi tüm oyuncularla yineleme yapman ve onları maksimum oyuncu sayısıyla en büyük farka sahip olan takıma ataman gerekir. Bunu, bir sonraki adımda oluşturacağın
FindTeamWithLargestDifference()
adlı yardımcı fonksiyon ile yapacaksın ancak öncelikle bir oyuncunun atanacağıTeamToAssign
adlı bir seçenek değişkeni başlat ve bunuFindTeamWithLargestDifference()
fonksiyonundan döndürülen değere ayarla.for (TeamPlayer:AllPlayers): var TeamToAssign:?team = false set TeamToAssign = FindTeamWithLargestDifference()
triad_infiltration_game
sınıf tanımındaFindTeamWithLargestDifference()
fonksiyonunu oluştur. Bu fonksiyon, maksimum oyuncu sayısıyla farkı en büyük olan takımı bulur ve isteğe bağlı birteam
değeri döndürür. Döndürülenteam
değerinin, oyuncu zaten en büyük farka sahip takımda olduğunda onun yeniden atanmasını önleyen bir seçenek olması gerekir.# Oyuncu sayısı, maksimum oyuncu sayısından # en farklı olan takımı bulur FindTeamWithLargestDifference():?team = Logger.Print("En küçük takımı bulmayı deniyor")
TeamToAssign
adlı isteğe bağlı bir takım değişkeni başlat. Bu değişken, oyuncu sayısı bakımından en büyük farka sahip takımın bir referansını ve oyuncu sayısı farkını takip eden birLargestDifference
tamsayısını kaydeder.# Oyuncu sayısı, maksimum oyuncu sayısından # en farklı olan takımı bulur. FindTeamWithLargestDifference():?team = Logger.Print("En küçük takımı bulmayı deniyor") var TeamToAssign:?team = false var LargestDifference:int = 0
- Şimdi takım listesinde yineleme yaparak ilgili takımın geçerli ve maksimum boyutlarını al.
var TeamToAssign:?team = false var LargestDifference:int = 0 for: CandidateTeam:Teams CurrentTeamSize := GetPlayspace().GetTeamCollection().GetAgents[CandidateTeam].Length MaximumTeamSize := TeamsAndTotals[CandidateTeam]
- Her bir takım için
DifferenceFromMaximum
değerini hesapla. Bu değer, bu takımın maksimum boyutu ile o anda sahip olduğu oyuncu sayısı arasındaki farktır. Takımın oyuncu sayısı farkıLargestDifference
değerinden büyükseLargestDifference
değeriniDifferenceFromMaximum
değerine ayarla veTeamToAssign
değerini biroption
içine al.for: CandidateTeam:Teams CurrentTeamSize := GetPlayspace().GetTeamCollection().GetAgents[CandidateTeam].Length MaximumTeamSize := TeamsAndTotals[CandidateTeam] do: Logger.Print("Takım kontrol ediliyor...") Logger.Print("Bu takımın maksimum boyutu {MaximumTeamSize}") DifferenceFromMaximum := MaximumTeamSize - CurrentTeamSize Logger.Print("Maksimum ile farkı {DifferenceFromMaximum}") if(LargestDifference < DifferenceFromMaximum): set LargestDifference = DifferenceFromMaximum set TeamToAssign = option{CandidateTeam} Logger.Print("Maksimum oyuncu sayısının altında bir takım bulundu: {DifferenceFromMaximum}")
- Son olarak
TeamToAssign
değerini döndür.FindTeamWithLargestDifference()
kodun şu anda aşağıdaki gibi görünmelidir:# Oyuncu sayısı, maksimum oyuncu sayısından # en farklı olan takımı bulur. FindTeamWithLargestDifference():?team = Logger.Print("En küçük takımı bulmayı deniyor") var TeamToAssign:?team = false var LargestDifference:int = 0 for: CandidateTeam:Teams CurrentTeamSize := GetPlayspace().GetTeamCollection().GetAgents[CandidateTeam].Length MaximumTeamSize := TeamsAndTotals[CandidateTeam] do: Logger.Print("Takım kontrol ediliyor...") Logger.Print("{CandidateTeamIndex + 1} takımının maksimum boyutu {MaximumTeamSize}") DifferenceFromMaximum := MaximumTeamSize - CurrentTeamSize Logger.Print("Maksimum sayı ile fark {DifferenceFromMaximum}") if(LargestDifference < DifferenceFromMaximum): set LargestDifference = DifferenceFromMaximum set TeamToAssign = option{CandidateTeam} Logger.Print("Minimum oyuncu sayısının altında bir takım bulundu: {DifferenceFromMaximum}") return TeamToAssign
BalanceTeams()
dizisine geri dönerekFortTeamCollection.AddToTeam[]
fonksiyonuyla yeni bir takım oluştur. Bu atama başarısız olursa oyuncu zaten en küçük takımdadır.var TeamToAssign:?team = false set TeamToAssign = FindTeamWithLargestDifference() if (AssignedTeam := TeamToAssign?, FortTeamCollection.AddToTeam[TeamPlayer, AssignedTeam]): Logger.Print("Oyuncuyu yeni bir takıma atamayı deniyor")
BalanceTeams()
fonksiyonun şu şekilde görünmelidir:# Tüm oyuncuları oyundaki tüm takımlar arasında dengeler BalanceTeams():void= Logger.Print("Takım dengeleme başlıyor") var AllPlayers:[]player := GetPlayspace().GetPlayers() set AllPlayers = Shuffle(AllPlayers) Logger.Print("AllPlayers Uzunluğu {AllPlayers.Length}") for (TeamPlayer:AllPlayers): var TeamToAssign:?team = false set TeamToAssign = FindTeamWithLargestDifference() if (AssignedTeam := TeamToAssign?, FortTeamCollection.AddToTeam[TeamPlayer, AssignedTeam]): Logger.Print("Oyuncu yeni bir takıma atandı")
Oyuncuları Doğma Alanlarına Işınlanma
Oyuncular sonunda en büyük farka sahip takıma katılacak olsa da doğru alanda doğmayabilirler. Bunun nedeni, dengeleme işlemiyle oyuncuların yeni bir takıma atanmadan önce doğmuş olmasıdır. Bu sorunu çözmek için oyuncuları takımlar dengelendikten sonra doğma yerlerine ışınlayan yeni bir fonksiyon oluşturmalısın.
triad_infiltration_game
sınıf tanımındaTeleportPlayersToStartLocations()
fonksiyonunu oluştur. Bu fonksiyon, dengeleme tamamlandıktan sonra oyuncuları takımlarının doğma yerine ışınlar.# Takım dengeleme tamamlandıktan sonra oyuncuları takımlarının doğma karesine ışınlar. TeleportPlayersToStartLocations():void= Logger.Print("Oyuncular başangıç konumlarına ışınlanıyor")
- Bir
for
döngüsündeTeams
dizisindeki her bir takım ile yineleme yap ve takımın dizisini alıp birTeamIndex
değişkeninde depola.# Takım dengeleme tamamlandıktan sonra oyuncuları takımlarının doğma karesine ışınlar. TeleportPlayersToStartLocations():void= Logger.Print("Oyuncular başangıç konumlarına ışınlanıyor") for: TeamIndex -> PlayerTeam:Teams
PlayerTeam
üzerindeki oyuncuları almak içinPlayerTeam
kullanarakGetAgents[]
çağrısı yap. Sonra o takımla ilişkili ışınlayıcıyı almak içinTeamIndex
kullanarakTeleporters
dizisinde bir dizin oluştur ve birTeamTeleporter
değişkeninde depola. Bu ışınlayıcının dönüşümünü birTransform
değişkeninde depola.# Takım dengeleme tamamlandıktan sonra oyuncuları takımlarının doğma karesine ışınlar. TeleportPlayersToStartLocations():void= Logger.Print("Oyuncular başangıç konumlarına ışınlanıyor") for: TeamIndex -> PlayerTeam:Teams TeamPlayers := GetPlayspace().GetTeamCollection().GetAgents[PlayerTeam] TeamTeleporter := Teleporters[TeamIndex] Transform := TeamTeleporter.GetTransform()
Teams
içindeki takımlarının sırasıylaTeleporters
içindeki ışınlayıcılarının sırasının eşleştiğinden emin ol. Casuslar 1. Takım iseTeleporters
içindeki ilk ışınlayıcı, Casuslar için olmalıdır. Editörde bu değerlerin doğru olup olmadığını iki kez kontrol et.- Şimdi ikinci bir
for
döngüsündeTeamPlayers
içindeki her bir oyuncu için yineleme yap veRespawn()
ileTransform
aktarma ve dönüşünü kullanarak oyuncuları ışınlayıcının dönüşümünde yeniden ortaya çıkar.TeleportPlayersToStartLocations()
fonksiyonun şu şekilde görünmelidir:# Takım dengeleme tamamlandıktan sonra oyuncuları takımlarının doğma karesine ışınlar. TeleportPlayersToStartLocations():void= Logger.Print("Oyuncular başangıç konumlarına ışınlanıyor") for: TeamIndex -> PlayerTeam:Teams TeamPlayers := GetPlayspace().GetTeamCollection().GetAgents[PlayerTeam] TeamTeleporter := Teleporters[TeamIndex] Transform := TeamTeleporter.GetTransform() do: for(TeamPlayer:TeamPlayers): TeamPlayer.Respawn(Transform.Translation, Transform.Rotation) Logger.Print("Bu oyuncu başlangıç konumuna ışınlandı")
OnBegin()
dizisindeAllPlayers
listesini karıştırdıktan sonra birBalanceTeams()
çağrısı ekle. Bunu yapmak, oyuncuların her defasında aynı takıma eklenmek yerine rastgele bir sırayla dengelenmesini sağlar. SonraTeleportPlayersToStartLocations()
fonksiyonunu çağırarak oyuncuları başlangıç konumlarına ışınla.OnBegin<override>()<suspends> : void = # Bütün Takımları al set Teams = GetPlayspace().GetTeamCollection().GetTeams() # Takımları daha sonra başvurmak üzere kaydet set MaybeInfiltrators = option{Teams[0]} set MaybeAttackers = option{Teams[1]} set MaybeDefenders = option{Teams[2]} if: Infiltrators := MaybeInfiltrators? Attackers := MaybeAttackers? Defenders := MaybeDefenders? Logger.Print("Üç takımın hepsi bulundu") set TeamsAndTotals[Infiltrators] = MaximumInfiltrators set TeamsAndTotals[Attackers] = MaximumAttackers set TeamsAndTotals[Defenders] = MaximumDefenders Logger.Print("TeamsAndTotals içinde üç takımın hepsi ayarlandı") then: BalanceTeams() TeleportPlayersToStartLocations() else: Logger.Print("Bütün takımlar bulunamadı, ada ayarlarında doğru takımları atadığından emin ol.")
-
Kodu kaydet, derle ve bölüme oynanış testi uygulamak için UEFN araç çubuğunda Oturumu Başlat düğmesine tıkla. Bölümüne oynanış testi uyguladığında her oyuncunun en büyük farka sahip takıma atanması ve o takımın doğma alanında doğması gerekir. Günlüğü kullanarak bu davranışı doğrula. Maksimum sayıdan daha az oyuncuya sahip olduğunda bu fonksiyonu test etmek için
triad_infiltration_game
içindeki takım başına maksimum oyuncu sayısını ayarlayabilirsin. Örneğin, tek başına test ederken oyuncunun atanmasını istediğin takımdaki maksimum oyuncu sayısını, diğer iki takımdan daha yüksek bir değere ayarlamayı dene. Saldırganlar takımına atanmasını istiyorsanMaximumAttackers
değerini daha yükseğe ayarla. Casuslar takımına atanmasını istiyorsanMaximumInfiltrators
değerini daha yükseğe ayarla.
Sonraki Adım
Bu eğitimin sonraki adımında oyunun başlangıcında ve oyuncular doğduklarında onlara nasıl silah verileceğini öğreneceksin.