Menu
CoddyTech

Singleton Deseni

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

Singleton deseni, bir sınıfın tam olarak bir nesnesi olmasını sağlar ve her betiğe bu nesneye ulaşmak için tek bir yol sunar. Oyunda yalnızca bir tane bulunan şeyler için kullanın: ayarlar, kayıt sistemi, skor takipçisi.

GDScript'te bir static var tek nesneyi tutar ve bir static func birisi istediğinde onu ilk kez oluşturur:

# 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 bir nesneye değil, sınıfa aittir; bu nedenle her betik aynı değişkeni görür. İlk çağrı onun boş olduğunu görür ve nesneyi oluşturur; sonraki her çağrı aynı nesneyi döndürür.

# 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 ve b aynı nesneyi tutan iki değişkendir; bu nedenle a üzerinden yapılan değişiklik b üzerinden de görünür. Nesnelerde ==, yalnızca her iki taraf da aynı nesne olduğunda true değerini verir.

GDScript, _init() yöntemini özel yapamaz; bu yüzden bir betiğin GameSettings.new() çağırıp ikinci bir nesne edinmesini engelleyen hiçbir şey yoktur. _instance adındaki alt çizgi ve get_instance() yöntemi bu konudaki uzlaşmadır: betikler nesneyi ister, asla kendileri oluşturmaz.

Bir Godot projesinde, paylaşılan tek bir nesne elde etmenin alışılmış yolu bir otomatik yüklemedir: Proje Ayarları'na kaydettiğin, Godot'un oyun başladığında bir kez oluşturduğu ve her betikte ada göre kullanılabilir hâle getirdiği bir betik. Bu, Godot'un senin için yönettiği bir Singleton'dır. Otomatik yüklemeler düzenleyicide ayarlandığından, buradaki alıştırmalar kalıbı kodda static var ile oluşturur.

challenge icon

Görev

Kolay

Bir oyundaki her coin, ortak bir skora eklenir. ScoreManager'ı bir Singleton yap:

  • Tek nesneyi static var tutar.
  • static func get_instance() bu nesneyi döndürür; ilk çağrıda nesneyi oluşturur. Oluşturduktan hemen sonra Score manager created yazdırır.
  • add_points(points), score değerine ekleme yapar.

coin.gd dosyasında collect(), coin'in value değerini ScoreManager.get_instance() aracılığıyla skora ekler.

Verilen kod, kaç olayın geleceğini okur ve ardından her satırda bir olay okur: coin VALUE yeni bir coin toplar, bonus POINTS puanları doğrudan ekler. Her olaydan sonra skoru, en sonda ise get_instance() işlevine yapılan iki çağrının aynı nesneyi döndürüp döndürmediğini yazdırır. coin 5 ve bonus 20 için çıktı şöyledir:

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

Kodunuzu score_manager.gd ve coin.gd dosyalarına yazın. main.gd verilen giriş/çıkış kodunu içerir ve düzenlenemez.

Kendin dene

extends Node

func _ready():
	# Sağlanan giriş/çıkış kodu: olduğu gibi bırakın
	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 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