Sygnały z argumentami
Część sekcji Programowanie obiektowe ścieżki GDScript w Coddy. Lekcja 38 z 65.
Sygnał może przenosić wartości. Wymień je w deklaracji, tak jak parametry funkcji:
signal damaged(amount: int, hp_left: int)
signal diedPrzekaż wartości do emit() w tej samej kolejności:
func take_damage(amount: int) -> void:
hp = maxi(hp - amount, 0)
damaged.emit(amount, hp)
if hp == 0:
died.emit()Połączona funkcja otrzymuje wartości jako parametry, więc potrzebuje jednego parametru dla każdej wartości:
hero.damaged.connect(_on_hero_damaged)
func _on_hero_damaged(amount: int, hp_left: int) -> void:
print("-%d HP, %d left" % [amount, hp_left])Typy w deklaracji opisują wartości: GDScript nie sprawdza ich podczas emisji. Niezgodność ujawnia się w funkcji odbierającej. Funkcja z nieprawidłową liczbą parametrów lub parametrem z typem, który nie może przechować wartości, powoduje błąd w wierszu emit(), a ta funkcja nie zostaje uruchomiona.
bind() dodaje własne wartości po wyemitowanych wartościach. Jedna metoda może wtedy nasłuchiwać kilku bohaterów i nadal wiedzieć, który z nich został trafiony:
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")Argumenty przekazują odbiorcy potrzebne dane, dzięki czemu nie musi ich odczytywać z obiektu emitującego sygnał. Nigdy nie łącz lambdy, która używa samego obiektu emitującego sygnał, na przykład hero.died.connect(func(): print(hero.hp)): lambda utrzymuje przy życiu hero, hero utrzymuje lambdę, żaden z nich nigdy nie zostaje zwolniony, a Godot zgłasza wycieki instancji po zakończeniu programu.
Wyzwanie
ŁatwyPortfel zgłasza każdą zmianę za pomocą sygnałów przenoszących liczby. W Wallet dodaj parametry do obu sygnałów i napisz dwie metody:
balance_changed(old_balance: int, new_balance: int)ipurchase_failed(price: int, missing: int)add(amount)dodaje monety i emitujebalance_changedz saldem przed zmianą i po niej.buy(price): gdy saldo jest wystarczające, odejmij cenę i wyemitujbalance_changed. W przeciwnym razie niczego nie zmieniaj i wyemitujpurchase_failedz ceną i liczbą brakujących monet.
Dostarczony kod łączy jedną funkcję z każdym sygnałem, odczytuje liczbę kolejnych poleceń, wykonuje każde polecenie (add 20, buy 15) i na koniec wyświetla liczbę pozostałych monet. Dla poleceń add 20, buy 15, buy 10, add 5, buy 10 wyświetla:
Balance: 0 -> 20
Balance: 20 -> 5
Cannot buy for 10: 5 coins missing
Balance: 5 -> 10
Balance: 10 -> 0
Coins left: 0Umieść swój kod w pliku wallet.gd. main.gd zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
extends Node
func _ready():
# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
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])
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneWprowadzenie do programowania obiektowegoKlasy a obiektySłowo kluczowe selfMetodyWłaściwościKonstruktor (_init)Powtórka – prosty kalkulator4Polimorfizm
Ponowne omówienie przesłaniania metodDuck typingKlasy i metody abstrakcyjneProjektowanie interfejsówPowtórzenie – kalkulator kształtów7Sygnały
Czym jest sygnał?Deklarowanie i emitowanieŁączenie z sygnałamiSygnały z argumentamiPodsumowanie — system zdrowia10Wzorce projektowe, część 2
Wzorzec poleceniaWzorzec adapteraWzorzec dekoratoraWzorzec metody szablonowejWzorzec stanuWzorzec kompozytu2Właściwości klas
Zmienne instancji a zmienne statyczneFunkcje statyczneSettery właściwościGettery właściwościPrywatne z konwencjiPodsumowanie — menedżer kont bankowych5Enkapsulacja
Elementy publiczne i prywatneWalidacja za pomocą setterówUkrywanie informacjiWłaściwości tylko do odczytuPodsumowanie – system ewidencji uczniów8Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieKlasy wewnętrzneWęzły jako komponentyRefCounted a NodeTypy wyliczeniowe w klasach11Projekt: Zarządzanie biblioteką
Przegląd projektuKlasy książki i użytkownika3Dziedziczenie
Podstawy dziedziczeniaSłowo kluczowe superNadpisywanie metodŁańcuchy dziedziczeniaSprawdzanie typów za pomocą isPodsumowanie – hierarchia pracowników6Metody specjalne
Wprowadzenie do metod wirtualnychMetoda _to_stringWłasne iteratoryPodsumowanie — własna lista9Wzorce projektowe — część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec ObserverWzorzec StrategyPoćwicz samodzielnie: Kompilator GDScript online