Sinyaller bir programlama modeli olan observer pattern‘ın Godot versiyonudur. Sinyaller sayesinde bir node başka nodeların dinleyip cevap verebileceği mesajlar gönderebilir. Mesela bir butona basıldı mı basılmadı mı anlamak için sinyalleri kullanabiliriz. Butonun durumunu surekli olarak kontrol etmektense, sadece basıldığı zaman yaydığı sinyali dinleyebiliriz.
Sinyaller sayesinde nodelar birbilerinin varlığını zorunlu tutmuyor ve bu da daha rahat organize edilebilen ve düzenlenebilen kod yazmamıza olanak veriyor. Sinyallerin amacını oyunun içindeki objeleri bağımsızlaştırmak olarak düşünebilirsiniz. Bu bağımsızlaştırma olayına decoupling deniyor.
Sinyalleri nasıl kullanacağımıza dair örneklere bakalım.
Timer Örneği
Sinyallerin nasıl çalıştığını görmek için Timer yani zamanlayıcı node’unu kullanalım. Yeni bir sahne oluşturun ve kök node olarak Node2D node’unu ekleyin. Ardından sahneye node listesinden bir Timer ve bir Sprite ekleyin.
Sprite 2 boyutlu görüntü göstermek için kullanılıyor. Timer ise ayarladığınız süre kadar zaman gectikten sonra timeout yani zaman aşımı sinyalini yayıyor.
Eklediginiz Sprite’ın göstereceği görüntüyü belirlemek icin bir Texture vermemiz lazim. İstediğiniz görüntü dosyasını kullanabilirsiniz. Biz “res://icon.png” lokasyonunda bulunan Godot’un logosunun resmini kullanacağız. Sprite node’unu seçin ve görüntüyü sürükleyerek Inspectordaki Texture özelliğinin yanında bulunan “[empty]” yazan yere bırakın. Aynı zamanda “[empty]” yazısına tıkladığınızda açılan menüden “Load” seçeneğine tıklayarak da görüntünüzü ekleyebilirsiniz.
Kök node’a bir script ekleyin. Sahneniz böyle gözüküyor olmalı:
Inspectordan Timer’ın “Autostart” özelliğini “On” yapın. Bu zamanlayıcımızın sahne açıldığında otomatik olarak çalışmasını sağlayacak.
“Inspector” sekmesinin yanında “Node” isimli bir sekme bulunuyor. Buraya tıklarsanız açılan pencerede seçili node’un yayabileceği bütün sinyalleri görebilirsiniz. Bizim ihtiyacımız olan sinyal “Timer” node’una özel olan “timeout” sinyali. Bu sinyal zamanlayıcı 0’a eriştiğinde yayılıyor.
Bir önceki derste sinyallerin editörün arayüzü kullanılarak nasıl bağlandığını görmüştük. Özet geçmek gerekirse, “timeout” sinyalini seçtikten sonra sağ alttaki “Connect” butonuna basınca açılan diyalogda sinyali bağlamak istediğiniz node’u seçip bağlantının yapılacağı fonksiyonun adını belirledikten sonra “Connect” butonuna basarak bağlantıyı oluşturabilirsiniz.
Bağlantıyı yaptığınız node’un bir scripti olduğundan emin olun.
Sinyalleri Kod ile Bağlamak
Sinyalleri aynı zamanda kod ile bağlayabiliriz. Bu yönteme sahnelerimizi kod ile instance ettiğimiz zaman ihtiyacımız var. Eğer “timeout” sinyalini arayüzü kullanarak bağladıysanız Timer node’unun Node sekmesinden sinyali seçip sağ alttaki “Disconnect” yani bağlantıyı kopar butonuna basın.
Bağlantımızı kod ile yapmak için “connect” fonksiyonunu kullanacağız. Bağlantımızın sahne çalıştırıldıktan hemen sonra yapılmasını istediğimiz için “_ready( )” fonksiyonun içine koyacağız.
“connect” fonksiyonunun kullanım biçimi:
<sinyali_yayan_node>.connect(<sinyal_ismi>, <hedef_node>, <hedef_fonksiyon_ismi>)
Kod aracılığı ile sahnemizden bir node’a erişmek için $ işaretini kullanıyoruz. Yani sahnemizdeki Timer isimli node’a $Timer şeklinde erişebiliyoruz. İstediğimiz node’a eriştikten sonra connect fonksiyonunu kullanarak bağlantımızı oluşturuyoruz.
extends Node2D

func _ready():
    $Timer.connect("timeout", self, "_on_Timer_timeout")

func _on_Timer_timeout():
    $Sprite.visible = !$Sprite.visible

Autostart özelliği sayesinde bittiği anda tekrar başlayan ve 1 saniyeye ayarlı olan zamanlayıcımız süresi bittiği zaman timeout sinyalini yayıyor. Bağlantımız sayesinde ise bu sinyal her yayıldığında “_on_Timer_timeout” fonksiyonumuz çalıştırılıyor. Bu fonksiyonun içinde ise Sprite node’unun visible özelliğini kullanarak görünürlüğünü değiştiriyoruz. Sahnenizi çalıştırırsanız Godot logosunun yanıp söndüğünü göreceksiniz.
Eğer bir şey görmüyorsanız sprite node’unuza texture eklediğinizden emin olun.
Özel Sinyaller
Şu ana kadar kullandığımız sinyaller Godot’un kendi sinyalleriydi fakat biz kod aracılığı ile kendi sinyallerimizi de oluşturabiliriz.
Kendi sinyalimizi beyan etmek için “signal” kelimesini kullanıyoruz.
extends Node2D


signal benim_sinyalim
Beyan edildikten sonra sinyalimiz Node sekmesinde belirecektir ve istersek önceden öğrendiğimiz şekilde sinyalimizi bağlayabiliriz.
Kendi sinyalimizi yaymak için “emit_signal” fonksiyonunu kullanıyoruz.
extends Node2D

signal benim_sinyalim

func _ready( ):
    emit_signal("benim_sinyalim")
İsteğe bağlı olarak sinyal beyanımıza bir veya birden fazla argüman ekleyebiliriz. Argüman isimleri parantez içinde yazılıyor.
extends Node2D

signal benim_sinyalim(arg_01, arg_02)
Sinyale değer devretmek için “emit_signal” fonksiyonunun ikinci argümanından itibaren değerlerinizi ekleyin.
extends Node2D

signal benim_sinyalim(arg_01, arg_02)

func _ready( ):

    emit_signal("benim_sinyalim", 128, false)
Godot’un bizim için tanımladığı sinyalleri ve kendi özel sinyallerimizi kullanarak bir çok farklı durumu belirleyip gereken tepkiyi verebiliriz.
Bu ders ile Godot’un temellerini bitirmiş olduk. Bir sonraki derste ilk oyunumuzu oluşturacağız ve bu seriyi noktalayacağız.