Menu
CoddyTech

Sinyallere Bağlanma

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

connect() çalıştırılacak fonksiyonu bir Callable olarak alır. Parantezleri olmadan bir yöntem adı yazın veya bir lambda yazın:

chest.opened.connect(_on_chest_opened)          # bu betiğin bir metodu
chest.opened.connect(quest_log.add_entry)       # başka bir nesnenin metodu
chest.opened.connect(func(): print("Creak!"))   # bir lambda

Godot, bir dinleyici yöntemini önce _on_, ardından sinyal yayıcısını, sonra da sinyali kullanarak adlandırır: _on_chest_opened. Bir sinyale birçok işlev bağlanabilir ve bu işlevler bağlandıkları sırayla çalışır.

Dinleyen bir nesne genellikle, sinyali gönderen nesneyi alan bir yöntemde kendi bağlantısını kurar:

# quest_log.gd
class_name QuestLog
extends RefCounted

var chests_opened := 0

func track(chest: Chest) -> void:
	if not chest.opened.is_connected(_on_chest_opened):
		chest.opened.connect(_on_chest_opened)

func untrack(chest: Chest) -> void:
	if chest.opened.is_connected(_on_chest_opened):
		chest.opened.disconnect(_on_chest_opened)

func _on_chest_opened() -> void:
	chests_opened += 1

Aynı işlevi aynı sinyale iki kez bağlamak bir hatadır; bağlı olmayan bir işlevin bağlantısını kesmek de öyle. Önce is_connected() kontrol eder. disconnect() dinlemeyi durdurur ve sonraki emit bu işlevi artık çalıştırmaz.

İkinci bağımsız değişken olarak CONNECT_ONE_SHOT değerini iletin; bağlantı ilk çağrısından sonra kendisini kaldırır: chest.opened.connect(_on_first_open, CONNECT_ONE_SHOT).

Bir lambda, oluşturulduğu sırada yerel bir değişkenin sahip olduğu değeri saklar. Bağlı bir lambda içindeki count += 1 bu kopyayı değiştirir ve _ready() içindeki count değeri 0 olarak kalır. QuestLog gibi, bir dinleyici nesnesinin üye değişkeninde sayaç tutun.

challenge icon

Görev

Kolay

Bir atış poligonunda, vurulduklarında hit sinyalini yayan hedefler vardır. Bunları dinleyen ScoreBoard sınıfını yaz:

  • watch(target), hedefin hit sinyalini _on_target_hit işlevine bağlar. Zaten izlenen bir hedefi izlemek hiçbir şeyi değiştirmez.
  • ignore(target) bağlantıyı keser. İzlenmeyen bir hedefi yok saymak hiçbir şeyi değiştirmez.
  • _on_target_hit(), points değerine 10 ekler ve Hit! Score: N yazdırır.

Bir hedefi iki kez izlemek veya izlenmeyen bir hedefi yok saymak hataya neden olmamalıdır; çünkü herhangi bir hata testi başarısız kılar. target.gd dosyası tamamlanmıştır.

Verilen kod hedef sayısını, ardından watch 0, ignore 0 ve shoot 0 gibi komutları okur ve son puanı yazdırır. İki hedef ve watch 0, shoot 0, shoot 1, watch 1, watch 1, shoot 1, ignore 0, shoot 0 komutları için şunu yazdırır:

Shot target 0
Hit! Score: 10
Shot target 1
Shot target 1
Hit! Score: 20
Shot target 0
Final score: 20

Kodunuzu score_board.gd ve target.gd dosyalarına yazın. 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 board := ScoreBoard.new()
	var targets: Array[Target] = []
	for i in int(OS.read_string_from_stdin()):
		targets.append(Target.new())
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		var target := targets[int(parts[1])]
		if parts[0] == "watch":
			board.watch(target)
		elif parts[0] == "ignore":
			board.ignore(target)
		else:
			print("Shot target ", parts[1])
			target.shoot()
	print("Final score: ", board.points)
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