Tam Kod
Oyuncuları asimetrik şekillerde dengeleyerek dinamik oyun deneyimleri oluşturan üç takımlı bir casusluk oyunu için tam kod aşağıdaki gibidir.
triad_infiltration_game.verse
using { /Fortnite.com/Devices }
using { /Fortnite.com/FortPlayerUtilities }
using { /Verse.org/Simulation }
using { /Verse.org/Random }
using { /UnrealEngine.com/Temporary/Diagnostics }
triad_infiltration_log_channel := class(log_channel){}
triad_infiltration := class(creative_device):
Logger:log = log{Channel := triad_infiltration_log_channel}
# Oyuncuların bir takıma katılamamasını önlemek için maksimum sayıyı ayarlamalısın
# Bunun için maksimum oyuncu sayısını, ada ayarlarında tüm Maximum(Team) değişkenlerinin toplamına ayarlamalısın.
# Casuslar Takımındaki maksimum oyuncu sayısı.
@editable
MaximumInfiltrators:int = 2
# Saldırganlar Takımındaki maksimum oyuncu sayısı.
@editable
MaximumAttackers:int = 4
# Savunmacılar Takımındaki maksimum oyuncu sayısı.
@editable
MaximumDefenders:int = 4
# Oyun başladıktan sonra oyuncuları takımlarının doğma karesine ışınlayan Işınlayıcıların dizisi.
@editable
Teleporters:[]teleporter_device = array{}
# Casusların görünmezliğini kontrol eden invisibility_manager koduna referans.
@editable
InvisibilityManager:invisibility_manager = invisibility_manager{}
# Her takım için silah vericilerin dizisi.
@editable
var WeaponGranters:[]item_granter_device = array{}
# Her takım için oyuncu doğma karelerinin dizisi.
@editable
PlayersSpawners:[]player_spawner_device = array{}
# Casuslar takımına referans.
var MaybeInfiltrators:?team = false
# Saldırganlar takımına referans.
var MaybeAttackers:?team = false
# Savunmacılar takımına referans.
var MaybeDefenders:?team = false
# Oyundaki tüm takımların dizisi.
var AllTeams:[]team = array{}
# Takımların maksimum oyuncu sayılarıyla eşleştirilmesi.
var TeamsAndTotals:[team]int = map{}
OnBegin<override>()<suspends>:void =
# Bütün takımları al.
set AllTeams = GetPlayspace().GetTeamCollection().GetTeams()
var AllPlayers:[]player = GetPlayspace().GetPlayers()
# Takımları daha sonra başvurmak üzere kaydet.
set MaybeInfiltrators = option{AllTeams[0]}
set MaybeAttackers = option{AllTeams[1]}
set MaybeDefenders = option{AllTeams[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:
#Yeni bir oyuncu oyuna katıldığında takımın yeniden dengelenmesine olanak tanıyan PlayerAddedEvent olayına bağlan.
GetPlayspace().PlayerAddedEvent().Subscribe(OnPlayerAdded)
for(PlayerSpawner:PlayersSpawners):
PlayerSpawner.SpawnedEvent.Subscribe(OnPlayerSpawn)
BalanceTeams()
Logger.Print("Takımlar dengelendi, görünmezlik kodu çağrılıyor")
InvisibilityManager.StartInvisibilityManager(AllTeams, AllPlayers, Infiltrators)
Sleep(0.25)
TeleportPlayersToStartLocations()
else:
Logger.Print("Bütün takımlar bulunamadı, ada ayarlarında doğru takımları atadığından emin ol.")
# Oyunculara Takımlar dizisindeki takımlarının dizinine göre bir silah verir,
# bunun için WeaponGranters dizisinde bir dizin oluşturur.
GrantTeamWeapon(InPlayer:player):void=
if(CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[InPlayer]):
for(TeamIndex -> PlayerTeam:AllTeams, PlayerTeam = CurrentTeam):
if(WeaponGranter := WeaponGranters[TeamIndex]):
WeaponGranter.GrantItem(InPlayer)
Logger.Print("{TeamIndex + 1} takımındaki bir oyuncuya bir silah verildi")
# Bir doğma karesinden herhangi bir oyuncu doğduğunda çalışır.
# Belirtilen SpawnedAgent değerini kullanarak GrantTeamWeapon fonksiyonunu çağırır.
OnPlayerSpawn(SpawnedAgent:agent):void=
if(SpawnedPlayer := player[SpawnedAgent]):
Logger.Print("Doğan oyuncuya bir silah vermeyi deniyor")
GrantTeamWeapon(SpawnedPlayer)
# Oyuna katılan yeni bir oyuncuyu işler.
OnPlayerAdded(InPlayer:player):void=
Logger.Print("Yeni bir Oyuncu katıldı, bir takıma atanıyor")
FortTeamCollection := GetPlayspace().GetTeamCollection()
# Yeni oyuncuyu en küçük takıma asimetrik olarak ata.
BalancePlayer(InPlayer)
for:
TeamIndex -> PlayerTeam:AllTeams
PlayerTeam = FortTeamCollection.GetTeam[InPlayer]
TeamTeleporter := Teleporters[TeamIndex]
Transform := TeamTeleporter.GetTransform()
do:
InPlayer.Respawn(Transform.Translation, Transform.Rotation)
Logger.Print(“Doğan oyuncu başlangıç konumuna ışınlandı”)
# Oyuncu bir casussa
# InvisibilityManager’da OnInfiltratorJoined fonksiyonunu çağır.
if(PlayerTeam = MaybeInfiltrators?):
InvisibilityManager.OnInfiltratorJoined(InPlayer)
# 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):
BalancePlayer(TeamPlayer)
# Her oyuncu için takım listesini yinele ve onları
# en az sayıda oyuncuya sahip takıma ya da eşitlik varsa başladıkları takıma ata.
BalancePlayer(InPlayer:player):void=
Logger.Print(“Oyuncu dengeleme başlıyor”)
var TeamToAssign:?team = false
set TeamToAssign = FindTeamWithLargestDifference()
if (AssignedTeam := TeamToAssign?, GetPlayspace().GetTeamCollection().AddToTeam[InPlayer, AssignedTeam]):
Logger.Print("Oyuncu yeni bir takıma atandı")
else:
Logger.Print("Bu oyuncu zaten en küçük takımdaydı")
# 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:
CandidateTeamIndex -> CandidateTeam:AllTeams
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 ile farkı {DifferenceFromMaximum}")
if(LargestDifference < DifferenceFromMaximum):
set LargestDifference = DifferenceFromMaximum
set TeamToAssign = option{CandidateTeam}
Logger.Print("Farkı {DifferenceFromMaximum} olan {CandidateTeamIndex + 1} takımı bulundu")
return TeamToAssign
# 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:AllTeams
TeamPlayers := GetPlayspace().GetTeamCollection().GetAgents[PlayerTeam]
TeamTeleporter := Teleporters[TeamIndex]
do:
for(TeamPlayer:TeamPlayers):
TeamTeleporter.Teleport(TeamPlayer)
Logger.Print("Bu oyuncu başlangıç konumuna ışınlandı")
invisibility.verse
using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
triad_invisibility_log_channel := class(log_channel){}
invisibility_manager := class(creative_device):
Logger:log = log{Channel := triad_invisibility_log_channel}
# Casuslar takımı için oyuncu doğma karelerinin dizisi
@editable
PlayersSpawners:[]player_spawner_device = array{}
# Casusların görünürlük bilgisinin takım arkadaşlarıyla paylaşılıp paylaşılmadığı.
@editable
IsVisibilityShared:logic = true
# Casusların hasar gördükten sonra ne kadar süreyle görünür olacağı.
@editable
VulnerableSeconds:float = 3.0
# Casusların hasar gördükten sonra ne kadar hızlı titreyeceğini belirtir.
@editable
FlickerRateSeconds:float = 0.4
# Oyundaki tüm takımların dizisi.
var AllTeams:[]team = array{}
# Oyuncuların titremeye devam edecekleri kalan saniye miktarıyla eşleştirilmesi.
var PlayerVisibilitySeconds:[agent]float = map{}
OnBegin<override>()<suspends>:void=
# Oyuncuları görünür yapan olaylara abone olmadan önce takımların dengelenmesini bekle.
Logger.Print("Takımların dengelenmesi bekleniyor...")
# Görünmezlik yöneticisi mantığını oluşturmaya başlar. Takım dengeleme bittikten sonra triad_infiltration sınıfından çağrılır
StartInvisibilityManager<public>(GameTeams:[]Takım, AllPlayers:[]player, Infiltrators:Takım):void=
Logger.Print("Görünmezlik kodu başlatıldı!")
set AllTeams = GameTeams
for(PlayerSpawner:PlayersSpawners):
PlayerSpawner.SpawnedEvent.Subscribe(OnPlayerSpawn)
# Bir oyuncu casus takımında doğduysa o oyuncu için bir OnInfiltratorDamaged fonksiyonu
# oluştur. Ardından, karakterini görünmez yap.
for(TeamPlayer:AllPlayers):
if:
FortCharacter:fort_character = TeamPlayer.GetFortCharacter[]
CurrentTeam:team := GetPlayspace().GetTeamCollection().GetTeam[TeamPlayer]
Logger.Print("Bu oyuncunun geçerli takımı alındı")
Infiltrators = CurrentTeam
set PlayerVisibilitySeconds[TeamPlayer] = 0.0
Logger.Print("Oyuncu PlayerVisibilitySeconds değerine eklendi")
then:
spawn{OnInfiltratorDamaged(TeamPlayer)}
Logger.Print("Oyuncu bir casus olarak doğdu, bu da onu görünmez yapıyor")
FortCharacter.Hide()
else:
Logger.Print("Bu oyuncu bir casus değil)")
# Fort_character'ını yinelemeli şekilde gizleyip göstererek bir aracının (oyuncu veya AI) görünürlüğünü titretir
FlickerCharacter(InCharacter:fort_character)<suspends>:void=
Logger.Print("FlickerCharacter() çağrıldı")
# Titreşim efekti oluşturmak için karakteri gizleme ve gösterme döngüsü.
loop:
InCharacter.Hide()
Sleep(FlickerRateSeconds)
InCharacter.Show()
Sleep(FlickerRateSeconds)
# Her döngüde karakterin titreme miktarı FlickerRateSeconds kadar azalır.
# Kalan süre 0'a ulaşırsa döngüden çık.
if:
TimeRemaining := set PlayerVisibilitySeconds[InCharacter.GetAgent[]] -= FlickerRateSeconds * 2
TimeRemaining <= 0.0
then:
InCharacter.Hide()
break
# Bir aracı (oyuncu veya AI) hasar aldığında görünürlüğünü titretir
OnInfiltratorDamaged(InAgent:agent)<suspends>:void=
Logger.Print("Bu karakter için titretme başlatılmaya çalışıyor")
TeamCollection := GetPlayspace().GetTeamCollection()
if (FortCharacter := InAgent.GetFortCharacter[]):
loop:
if(IsVisibilityShared?, CurrentTeam := TeamCollection.GetTeam[InAgent], TeamAgents := TeamCollection.GetAgents[CurrentTeam]):
# Her bir takım arkadaşını PlayerVisibility saniye içinde ayarla ve bir FlickerEvent oluştur.
for(Teammate:TeamAgents):
Logger.Print("Bir Takım Arkadaşı için StartOrResetFlickering çağrılıyor")
StartOrResetFlickering(Teammate)
else:
# Sadece hasar gören karakteri titret.
Logger.Print("InAgent için StartOrResetFlickering çağrılıyor")
StartOrResetFlickering(InAgent)
FortCharacter.DamagedEvent().Await()
# Aracı görünmezse yeni bir titreme olayı başlatır, görünmez değilse
# aracının devam eden titremesini sıfırlar.
StartOrResetFlickering(InAgent:agent):void=
if (not IsFlickering[InAgent], FortCharacter := InAgent.GetFortCharacter[]):
Logger.Print("Bu karakter için YENİ FlickerEvent başlatmayı deniyor")
# Yeni titreşim başlatıldı.
if (set PlayerVisibilitySeconds[InAgent] = VulnerableSeconds):
spawn{FlickerCharacter(FortCharacter)}
Logger.Print("Bu karakter için bir FlickerEvent üretildi")
else:
# Devam eden titreşimi sıfırla.
if (set PlayerVisibilitySeconds[InAgent] = VulnerableSeconds):
Logger.Print("Karakterin FlickerTimer süresini VulnerableSeconds değerine sıfırla")
# Oyuncunun titreme süresi kalıp kalmadığını döndürür
IsFlickering(InAgent:agent)<decides><transacts>:void=
PlayerVisibilitySeconds[InAgent] > 0.0
# Oyuna yeni bir casus katıldığında bir OnInfiltratorDamaged fonksiyonu oluşturur
OnInfiltratorJoined<public>(InAgent:agent):void=
spawn{OnInfiltratorDamaged(InAgent)}
# Casus doğma karesinde bir oyuncunun doğmasını işler
OnPlayerSpawn(SpawnedAgent:agent):void=
Logger.Print(“Casus doğma karesinde şimdi bir oyuncu doğdu!”)
if:
FortCharacter:fort_character = SpawnedAgent.GetFortCharacter[]
CurrentTeam := GetPlayspace().GetTeamCollection().GetTeam[SpawnedAgent]
AllTeams[0] = CurrentTeam
Logger.Print("Oyuncu bir casus olarak doğdu, bu da onu görünmez yapıyor")
then:
FortCharacter.Hide()
item_capture_manager.verse
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Fortnite.com/Characters }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
triad_item_capture_log_channel := class(log_channel){}
item_capture_manager := class(creative_device):
Logger:log = log{Channel := triad_item_capture_log_channel}
# Ele geçirilecek eşyayı çıkaran ele geçirilecek eşya oluşturma yeri.
@editable
CaptureItemSpawner:capture_item_spawner_device = capture_item_spawner_device{}
# CaptureItemSpawner’dan bir eşyayı tuttuğunda oyuncunun başının
# üzerinde duracak bir nesne.
@editable
CaptureItemIndicator:creative_prop = creative_prop{}
# Her takımın hedeflerinin nerede olduğunu haritada gösteren gösterge.
@editable
MapIndicator:map_indicator_device = map_indicator_device{}
# CaptureItemIndicator göstergesinin konumunu ne sıklıkla güncelleyeceğini belirtir.
@editable
UpdateRateSeconds:float = 0.15
# CaptureItemIndicator göstergesinin oyuncunun başından ne kadar yüksekte duracağını belirtir.
@editable
VerticalOffset:float = 180.0
# Bir oyuncu Ele Geçirilecek Eşyayı tuttuğunda bir mesaj görüntüler.
@editable
ItemGrabbedMessageDevice:hud_message_device = hud_message_device{}
# CaptureItem ve Harita göstergelerini döndürmeden önce beklenmesi gereken süre.
# Negatif bir süre, hedef yeniden alınmadıkça göstergelerin asla geri dönmeyeceğini
# belirtir.
@editable
ReturnTime:float = 10.0
# Bir oyuncu ele geçirilecek eşyayı aldığında puan verir.
@editable
ScoreManagerDevice:score_manager_device = score_manager_device{}
OnBegin<override>()<suspends>:void=
CaptureItemSpawner.ItemPickedUpEvent.Subscribe(OnItemPickedUp)
CaptureItemSpawner.ItemCapturedEvent.Subscribe(OnItemCaptured)
CaptureItemSpawner.ItemDroppedEvent.Subscribe(OnItemDropped)
SpawnerTransform := CaptureItemSpawner.GetTransform()
# CaptureItemIndicator ve MapIndicator’ı haritanın altında alanın dışında bir yere gizleyerek çıkma yerine geri ışınla.
CaptureItemIndicator.MoveTo(SpawnerTransform.Translation + vector3{Z := VerticalOffset * 10.0}, SpawnerTransform.Rotation, UpdateRateSeconds)
MapIndicator.MoveTo(SpawnerTransform.Translation + vector3{Z := VerticalOffset * 10.0}, SpawnerTransform.Rotation, UpdateRateSeconds)
Logger.Print("Çıkma yerini yakalamak için İşaret döndürüldü")
# Bir oyuncu hedefi yakaladığında her oyuncuya sinyal gönder.
OnItemPickedUp(InAgent:agent):void=
Logger.Print(“Hedef Tutuldu”)
if(FortCharacter := InAgent.GetFortCharacter[]):
ItemGrabbedMessageDevice.Show()
spawn{FollowCharacter(FortCharacter)}
# Bir oyuncu eşya bıraktığında ReturnTime 0’dan büyükse
# bir WaitForReturn() fonksiyonu oluştur.
OnItemDropped(InAgent:agent):void=
Logger.Print("Hedef Bırakıldı”)
if(ReturnTime >= 0.0):
spawn{WaitForReturn()}
else:
Logger.Print(“Bırakılan hedef geri dönmez”)
# Eşya ele geçirildiğinde, ele geçiren takıma puan ver ve göstergeleri geri gönder.
OnItemCaptured(CapturingAgent:agent):void=
Logger.Print("Hedef Yakalandı")
ScoreManagerDevice.Activate()
ReturnIndicators()
# ReturnTime değeri kadar bir süre bekle, ardından göstergeleri geri gönder.
WaitForReturn()<suspends>:void=
Logger.Print(“Göstergeleri geri döndürmek için bekleniyor...”)
# Ele geçirilecek eşya süre dolmadan önce alınmadıysa CaptureItem ve
# Harita göstergelerini geri döndür.
ShouldReturn:logic := race:
block:
Sleep(ReturnTime)
true
block:
CaptureItemSpawner.ItemPickedUpEvent.Await()
yanlış
if(ShouldReturn?):
ReturnIndicators()
# CaptureItemIndicator’ın bir oyuncuyu sürekli olarak başının üstünde takip etmesine neden olur.
# CaptureItemIndictator için güncelleme döngüsü ile oyuncunun
# eşyayı ele geçirip geçirmediği, bırakıp bırakmadığı veya avlanıp avlanmadığı arasında yarış yapar.
FollowCharacter(FortCharacter:fort_character)<suspends>:void=
Logger.Print("FollowCharacter fonksiyonu üretildi")
race:
loop:
Transform := FortCharacter.GetTransform()
spawn{CaptureItemIndicator.MoveTo(Transform.Translation + vector3{Z := VerticalOffset}, Transform.Rotation, UpdateRateSeconds)}
spawn{MapIndicator.MoveTo(Transform.Translation + vector3{Z := VerticalOffset}, Transform.Rotation, UpdateRateSeconds)}
# Bu döngünün her simülasyon güncellemesinde yalnızca bir kez çalıştığından emin olmak istiyoruz, bu nedenle bir oyun tiki uyuyoruz.
Sleep(0.0)
CaptureItemSpawner.ItemCapturedEvent.Await()
CaptureItemSpawner.ItemDroppedEvent.Await()
FortCharacter.EliminatedEvent().Await()
Logger.Print("Hedef düşürüldü veya yakalandı")
# Haritayı ve ele geçirilecek eşya göstergelerini, çıkma yerlerinin üzerindeki başlangıç konumlarına geri döndürür.
ReturnIndicators():void=
SpawnerTransform := CaptureItemSpawner.GetTransform()
# CaptureItemIndicator ve MapIndicator’ı haritanın yukarısında alanın dışında bir yere gizleyerek çıkma yerine geri ışınla.
spawn{CaptureItemIndicator.MoveTo(SpawnerTransform.Translation + vector3{Z := VerticalOffset * 10.0}, SpawnerTransform.Rotation, UpdateRateSeconds)}
spawn{MapIndicator.MoveTo(SpawnerTransform.Translation + vector3{Z := VerticalOffset * 10.0}, SpawnerTransform.Rotation, UpdateRateSeconds)}
Logger.Print(“Göstergeler ele geçirilecek eşya oluşturma yerine döndürüldü”)
Kendi Kendine Yapabileceklerin
Bu kılavuzu tamamlayarak oyuncu takımlarını asimetrik şeklide dengeleyen bir oyun oluşturmak için Verse'ü nasıl kullanacağını öğrendin.
Öğrendiklerini kullanarak aşağıdakileri yapmayı dene:
- Casuslar, Saldırganlar ve Savunmacılar için farklı parametrelerle oynamayı deneyerek ideal oyun deneyimini oluştur. Casusların yakın dövüş silahları olsaydı ne olurdu? Savunmacılar da görünmez olsa ne olurdu?
- Casuslar ve Saldırganlar aynı hedef için mücadele edebilir mi? Zafer koşulunu değiştirebilir misin?