Was ist ein Signal?
Teil des Abschnitts Objektorientierte Programmierung der GDScript-Journey von Coddy. Lektion 35 von 65.
Während ein Spiel läuft, passieren Dinge mit Objekten: Eine Münze wird eingesammelt, eine Tür öffnet sich, die hp des Helden sinkt auf 0. Andere Teile des Programms reagieren auf diese Ereignisse: Der Punktestand steigt, ein Ton erklingt, der Game-Over-Bildschirm erscheint.
Ein Signal ist eine Nachricht, die ein Objekt sendet, wenn etwas mit ihm geschieht. Das Objekt sendet das Signal aus, und jede mit diesem Signal verbundene Funktion wird ausgeführt:
# coin.gd
class_name Coin
extends RefCounted
signal collected
func collect() -> void:
print("Coin picked up")
collected.emit()signal collected deklariert das Signal und collected.emit() sendet es. Die Münze weiß nicht, wer zuhört. Der Code, der sich für Münzen interessiert, verbindet eine seiner eigenen Funktionen mit dem Signal:
# main.gd
func _ready():
var coin := Coin.new()
coin.collected.connect(_on_coin_collected)
coin.collect()
print("Done")
func _on_coin_collected() -> void:
print("Score +1")Die Ausgabe lautet Coin picked up, Score +1, Done. Beim Auslösen werden die verbundenen Funktionen sofort ausgeführt, bevor die Zeile nach emit() ausgeführt wird. Ein Signal ohne verbundene Funktionen bewirkt beim Auslösen nichts.
Ohne ein Signal müsste collect() den Code für die Punktzahl selbst aufrufen, sodass jede Münze eine Referenz auf die Punktetafel bräuchte. Mit einem Signal kündigt die Münze nur das Ereignis an, und beliebig viele Listener oder auch gar keiner können darauf reagieren.
Godots eigene Knoten funktionieren genauso: Ein Button löst pressed aus, wenn er angeklickt wird, und ein Timer löst timeout aus, wenn seine Zeit abläuft.
Aufgabe
EinfachEin Briefkasten kündigt neue Post mit einem Signal an. Mailbox deklariert bereits signal mail_arrived und hat einen letters-Zähler. Schreibe deliver(kind):
- Wenn
kind"letter"ist, addiere1zulettersund sendemail_arrivedaus. - Jede andere Art (eine Werbung, ein Flyer) wird weggeworfen: Nichts ändert sich und nichts wird ausgesendet.
Der bereitgestellte Code verbindet eine Funktion, die You've got mail! ausgibt, liest dann, wie viele Zeilen folgen, und stellt jede davon zu. Die Zeile away trennt die Verbindung zu dieser Funktion, und home verbindet sie wieder. Ein Brief, der ankommt, während du weg bist, wird also gezählt, aber nicht angekündigt. Für die Zeilen letter, ad, away, letter gibt der Code Folgendes aus:
Delivering: letter
You've got mail!
Delivering: ad
Delivering: letter
Letters: 2Dein Code gehört in mailbox.gd. main.gd enthält den bereitgestellten Ein-/Ausgabecode und kann nicht bearbeitet werden.
Probier es selbst
extends Node
func _ready():
# Bereitgestellter Ein-/Ausgabecode: unverändert lassen
var mailbox := Mailbox.new()
mailbox.mail_arrived.connect(_on_mail_arrived)
var count := int(OS.read_string_from_stdin())
for i in count:
var line := OS.read_string_from_stdin()
if line == "away":
mailbox.mail_arrived.disconnect(_on_mail_arrived)
elif line == "home":
mailbox.mail_arrived.connect(_on_mail_arrived)
else:
print("Delivering: ", line)
mailbox.deliver(line)
print("Letters: ", mailbox.letters)
func _on_mail_arrived() -> void:
print("You've got mail!")
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas Schlüsselwort selfMethodenEigenschaftenKonstruktor (_init)Wiederholung – Einfacher Taschenrechner4Polymorphie
Methodenüberschreibung erneut betrachtetDuck-TypisierungAbstrakte Klassen und MethodenSchnittstellendesignRückblick – Formrechner7Signale
Was ist ein Signal?Deklarieren und AuslösenMit Signalen verbindenSignale mit ArgumentenRückblick – Gesundheitssystem2Klassenattribute
Instanz- vs. statische VariablenStatische FunktionenProperty-SetterProperty-GetterPrivat nach KonventionWiederholung – Bankkontenverwaltung5Kapselung
Öffentliche und private MemberValidierung mit SetternInformationsverbergenSchreibgeschützte EigenschaftenRückblick – System zur Schülerverwaltung8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungInnere KlassenNodes als KomponentenRefCounted vs. NodeEnums in Klassen11Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Vererbung
Grundlegende VererbungDas Schlüsselwort superMethodenüberschreibungVererbungskettenTypprüfungen mit isWiederholung – Mitarbeiterhierarchie6Spezielle Methoden
Einführung in virtuelle MethodenDie _to_string-MethodeBenutzerdefinierte IteratorenRückblick – Benutzerdefinierte Liste9Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterBeobachter-MusterStrategie-Muster12Abschließende Herausforderungen
E-Learning-PlattformBankensystemEntwicklung von SpielfigurenFahrzeugvermietungÜbe selbstständig: Online-GDScript-Compiler