Menu
CoddyTech

Argümanlı Sinyaller

Coddy'nin GDScript Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 38 / 65.

Bir sinyal değerler taşıyabilir. Bunları, bir fonksiyonun parametreleri gibi bildirimde listele:

signal damaged(amount: int, hp_left: int)
signal died

Değerleri emit() işlevine aynı sırayla aktar:

func take_damage(amount: int) -> void:
	hp = maxi(hp - amount, 0)
	damaged.emit(amount, hp)
	if hp == 0:
		died.emit()

Bağlı bir işlev, değerleri parametreleri olarak alır; bu nedenle her değer için bir parametreye ihtiyaç duyar:

hero.damaged.connect(_on_hero_damaged)

func _on_hero_damaged(amount: int, hp_left: int) -> void:
	print("-%d HP, %d left" % [amount, hp_left])

Bildirimin içindeki türler değerleri belgeler: GDScript, sinyali yaydığınızda bunları denetlemez. Uyumsuzluk, alıcı işlevde ortaya çıkar. Yanlış sayıda parametresi olan bir işlev ya da değeri tutamayan tür belirtilmiş bir parametre, emit() satırında hataya yol açar ve bu işlev çalışmaz.

bind(), yayımlanan değerlerden sonra kendi değerlerinizi ekler. Böylece bir yöntem birkaç kahramanı dinleyebilir ve yine de hangisinin darbe aldığını bilebilir:

ada.damaged.connect(_on_damaged.bind("Ada"))
bo.damaged.connect(_on_damaged.bind("Bo"))

func _on_damaged(amount: int, hp_left: int, who: String) -> void:
	print(who, " lost ", amount, " HP")

Argümanlar, bir dinleyiciye ihtiyaç duyduğu verileri sağlar; böylece dinleyici bu verileri yayıcıdan okumak zorunda kalmaz. Yayıcı nesnenin kendisini kullanan bir lambda'yı asla bağlamayın; örneğin hero.died.connect(func(): print(hero.hp)): lambda hero'yu canlı tutar, hero da lambda'yı tutar; ikisi de hiçbir zaman serbest bırakılmaz ve program sona erdiğinde Godot bellek sızıntısı olan örnekleri bildirir.

challenge icon

Görev

Kolay

Bir cüzdan, sayıları taşıyan sinyallerle her değişikliği bildirir. Wallet içinde, her iki sinyale de parametreleri ekleyin ve iki yöntemi yazın:

  • balance_changed(old_balance: int, new_balance: int) ve purchase_failed(price: int, missing: int)
  • add(amount) madeni para ekler ve önceki ve sonraki bakiyeyle birlikte balance_changed sinyalini gönderir.
  • buy(price): Bakiye yeterliyse fiyatı çıkarır ve balance_changed sinyalini gönderir. Aksi takdirde hiçbir şeyi değiştirmez ve fiyatı ve eksik olan madeni para sayısını içeren purchase_failed sinyalini gönderir.

Verilen kod, her sinyale bir işlev bağlar, kaç komutun geleceğini okur, her komutu (add 20, buy 15) çalıştırır ve sonunda kalan madeni paraları yazdırır. add 20, buy 15, buy 10, add 5, buy 10 için şu çıktıyı verir:

Balance: 0 -> 20
Balance: 20 -> 5
Cannot buy for 10: 5 coins missing
Balance: 5 -> 10
Balance: 10 -> 0
Coins left: 0

Kodunuz wallet.gd dosyasına yazılır. main.gd, verilen girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

extends Node

func _ready():
	# Sağlanan giriş/çıkış kodu: olduğu gibi bırakın
	var wallet := Wallet.new()
	wallet.balance_changed.connect(_on_balance_changed)
	wallet.purchase_failed.connect(_on_purchase_failed)
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		if parts[0] == "add":
			wallet.add(int(parts[1]))
		else:
			wallet.buy(int(parts[1]))
	print("Coins left: ", wallet.balance)

func _on_balance_changed(old_balance: int, new_balance: int) -> void:
	print("Balance: %d -> %d" % [old_balance, new_balance])

func _on_purchase_failed(price: int, missing: int) -> void:
	print("Cannot buy for %d: %d coins missing" % [price, missing])
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online GDScript derleyicisi