Menu
CoddyTech

Mit Signalen verbinden

Teil des Abschnitts Objektorientierte Programmierung der GDScript-Journey von Coddy. Lektion 37 von 65.

connect() erwartet als Callable die auszuführende Funktion. Gib den Namen einer Methode ohne Klammern an oder schreibe eine Lambda-Funktion:

chest.opened.connect(_on_chest_opened)          # eine Methode dieses Skripts
chest.opened.connect(quest_log.add_entry)       # eine Methode eines anderen Objekts
chest.opened.connect(func(): print("Creak!"))   # ein Lambda-Ausdruck

Godot benennt eine empfangende Methode mit _on_, dann dem Auslöser und anschließend dem Signal: _on_chest_opened. Ein Signal kann mit mehreren Funktionen verbunden sein, die in der Reihenfolge ausgeführt werden, in der sie verbunden wurden.

Ein Objekt, das auf ein Signal wartet, verbindet sich normalerweise selbst in einer Methode, die den Sender entgegennimmt:

# 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

Dieselbe Funktion zweimal mit demselben Signal zu verbinden, ist ein Fehler, ebenso wie das Trennen einer Funktion, die nicht verbunden ist. is_connected() prüft dies zuerst. disconnect() beendet das Lauschen, und beim nächsten Auslösen wird diese Funktion nicht mehr ausgeführt.

Übergib CONNECT_ONE_SHOT als zweites Argument, und die Verbindung entfernt sich nach ihrem ersten Aufruf selbst: chest.opened.connect(_on_first_open, CONNECT_ONE_SHOT).

Eine Lambda-Funktion behält den Wert, den eine lokale Variable hatte, als die Lambda-Funktion erstellt wurde. count += 1 innerhalb einer verbundenen Lambda-Funktion ändert diese Kopie, und count in _ready() bleibt 0. Führe einen Zähler in einer Member-Variable eines Listener-Objekts, wie es QuestLog tut.

challenge icon

Aufgabe

Einfach

Ein Schießstand hat Ziele, die beim Treffer hit auslösen. Schreibe das ScoreBoard, das auf sie hört:

  • watch(target) verbindet das Signal hit des Ziels mit _on_target_hit. Ein Ziel zu beobachten, das bereits beobachtet wird, ändert nichts.
  • ignore(target) trennt die Verbindung. Ein Ziel zu ignorieren, das nicht beobachtet wird, ändert nichts.
  • _on_target_hit() addiert 10 zu points und gibt Hit! Score: N aus.

Ein Ziel zweimal zu beobachten oder ein nicht beobachtetes Ziel zu ignorieren darf keinen Fehler verursachen, da jeder Fehler den Test fehlschlagen lässt. target.gd ist vollständig.

Der bereitgestellte Code liest die Anzahl der Ziele und anschließend Befehle wie watch 0, ignore 0 und shoot 0 und gibt die Endpunktzahl aus. Bei zwei Zielen und den Befehlen watch 0, shoot 0, shoot 1, watch 1, watch 1, shoot 1, ignore 0, shoot 0 gibt er Folgendes aus:

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

Dein Code gehört in score_board.gd und target.gd. main.gd enthält den bereitgestellten Eingabe-/Ausgabecode und kann nicht bearbeitet werden.

Probier es selbst

extends Node

func _ready():
	# Vorgegebener Ein-/Ausgabecode: unverändert lassen
	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 iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-GDScript-Compiler