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_gamesı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
AllPlayersdeğişken dizisinde depola. Ardından,AllPlayerslistesini 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ğıTeamToAssignadlı 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_gamesı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ı birteamdeğeri döndürür. Döndürülenteamdeğ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")TeamToAssignadlı 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 birLargestDifferencetamsayı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
DifferenceFromMaximumdeğ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ıLargestDifferencedeğerinden büyükseLargestDifferencedeğeriniDifferenceFromMaximumdeğerine ayarla veTeamToAssigndeğerini biroptioniç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
TeamToAssigndeğ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_gamesı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
fordöngüsündeTeamsdizisindeki her bir takım ile yineleme yap ve takımın dizisini alıp birTeamIndexdeğ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çinPlayerTeamkullanarakGetAgents[]çağrısı yap. Sonra o takımla ilişkili ışınlayıcıyı almak içinTeamIndexkullanarakTeleportersdizisinde bir dizin oluştur ve birTeamTeleporterdeğişkeninde depola. Bu ışınlayıcının dönüşümünü birTransformdeğ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()Teamsiçindeki takımlarının sırasıylaTeleportersiçindeki ışınlayıcılarının sırasının eşleştiğinden emin ol. Casuslar 1. Takım iseTeleportersiç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
fordöngüsündeTeamPlayersiçindeki her bir oyuncu için yineleme yap veRespawn()ileTransformaktarma 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()dizisindeAllPlayerslistesini 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_gameiç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ı istiyorsanMaximumAttackersdeğerini daha yükseğe ayarla. Casuslar takımına atanmasını istiyorsanMaximumInfiltratorsdeğ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.