Menu
CoddyTech

Wzorzec Singleton

Część sekcji Programowanie obiektowe ścieżki GDScript w Coddy. Lekcja 46 z 65.

Wzorzec Singleton gwarantuje, że klasa ma dokładnie jeden obiekt i zapewnia każdemu skryptowi jeden sposób dostępu do niego. Używaj go w przypadku elementów, które w grze występują tylko w jednym egzemplarzu: ustawień, systemu zapisu, menedżera wyników.

W GDScript static var przechowuje pojedynczy obiekt, a static func tworzy go za pierwszym razem, gdy ktoś o niego poprosi:

# game_settings.gd
class_name GameSettings
extends RefCounted

static var _instance: GameSettings = null

var volume := 50

static func get_instance() -> GameSettings:
	if _instance == null:
		_instance = GameSettings.new()
		print("Creating settings")
	return _instance

_instance należy do klasy, a nie do obiektu, więc każdy skrypt widzi tę samą zmienną. Pierwsze wywołanie stwierdza, że jest pusta, i tworzy obiekt; każde kolejne wywołanie zwraca ten sam obiekt.

# main.gd
var a := GameSettings.get_instance()
var b := GameSettings.get_instance()
a.volume = 80
print(b.volume)
print(a == b)
Creating settings
80
true

a i b to dwie zmienne przechowujące jeden obiekt, więc zmiana dokonana za pośrednictwem a jest widoczna przez b. W przypadku obiektów == ma wartość true tylko wtedy, gdy obie strony są tym samym obiektem.

GDScript nie może uczynić funkcji _init() prywatną, więc nic nie powstrzymuje skryptu przed wywołaniem GameSettings.new() i uzyskaniem drugiego obiektu. Podkreślenie w _instance i metoda get_instance() to umowa: skrypty proszą o obiekt, nigdy go nie tworzą.

W projekcie Godot zwykle uzyskuje się jeden współdzielony obiekt za pomocą autoload: skryptu zarejestrowanego w ustawieniach projektu, który Godot tworzy raz po uruchomieniu gry i udostępnia pod nazwą w każdym skrypcie. To Singleton, którym Godot zarządza za Ciebie. Autoloady konfiguruje się w edytorze, więc w tych wyzwaniach wzorzec jest tworzony w kodzie za pomocą static var.

challenge icon

Wyzwanie

Łatwy

Każda moneta w grze zwiększa jeden wspólny wynik. Zrób z ScoreManager singleton:

  • static var przechowuje jedyny obiekt.
  • static func get_instance() zwraca go, tworząc go przy pierwszym wywołaniu. Zaraz po jego utworzeniu wypisuje Score manager created.
  • add_points(points) dodaje punkty do score.

W pliku coin.gd funkcja collect() dodaje value monety do wyniku za pośrednictwem ScoreManager.get_instance().

Dostarczony kod odczytuje liczbę kolejnych zdarzeń, a następnie po jednym zdarzeniu w każdym wierszu: coin VALUE zbiera nową monetę, a bonus POINTS dodaje punkty bezpośrednio. Po każdym zdarzeniu wypisuje wynik, a na końcu informację, czy dwa wywołania get_instance() zwracają ten sam obiekt. Dla coin 5 i bonus 20 wynik to:

Score manager created
Score: 5
Score: 25
Same object: true

Twój kod umieść w plikach score_manager.gd i coin.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 count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		if parts[0] == "coin":
			Coin.new(int(parts[1])).collect()
		elif parts[0] == "bonus":
			ScoreManager.get_instance().add_points(int(parts[1]))
		print("Score: %d" % ScoreManager.get_instance().score)
	print("Same object: %s" % (ScoreManager.get_instance() == ScoreManager.get_instance()))
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator GDScript online