Menu
CoddyTech

Komut Kalıbı

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

Command kalıbı bir eylemi nesneye dönüştürür. Nesne, eylemi gerçekleştirmek için gereken her şeyi saklar; böylece onu bir listede tutabilir, daha sonra çalıştırabilir veya geri alabilirsin.

Her komutun, soyut bir üst sınıf tarafından bildirilen aynı iki yöntemi vardır:

# command.gd
@abstract
class_name Command
extends RefCounted

@abstract func execute() -> void
@abstract func undo() -> void

Konkret bir komut, üzerinde işlem yaptığı ve alıcı olarak adlandırılan nesneyi ve eylemin verilerini tutar. Burada alıcı, var x := 0 değerine sahip bir Hero'dur:

# move_command.gd
class_name MoveCommand
extends Command

var hero: Hero
var dx: int

func _init(target: Hero, step: int) -> void:
	hero = target
	dx = step

func execute() -> void:
	hero.x += dx

func undo() -> void:
	hero.x -= dx

Çağırıcı komutları çalıştırır ve onları hatırlar. Bir komutun ne yaptığını bilmesi gerekmez:

# command_history.gd
class_name CommandHistory
extends RefCounted

var done: Array[Command] = []

func run(command: Command) -> void:
	command.execute()
	done.append(command)

func undo_last() -> void:
	if done.is_empty():
		return
	var last: Command = done.pop_back()
	last.undo()
# main.gd
var hero := Hero.new()
var history := CommandHistory.new()
history.run(MoveCommand.new(hero, 3))
history.run(MoveCommand.new(hero, 2))
print(hero.x)
history.undo_last()
print(hero.x)
5
3

Geçmiş bir yığındır: pop_back() en yeni komutu alır, bu nedenle geri alma işlemi eylemler arasında ters sırayla geriye doğru ilerler. Aynı nesneler, tuşları yeniden eşlemenizi (bir tuş bir komuta eşlenir), tekrar oynatmaları (kaydedilmiş listeyi yeniden çalıştırma) ve sıra kuyruklarını da sağlar.

Başvurular tek yönlüdür: komutlar kahramanı gösterir, kahraman ise onlar hakkında hiçbir şey bilmez. Kahraman da komutlarını saklasaydı, nesneler birbirlerini canlı tutar ve asla bellekten serbest bırakılmazdı.

challenge icon

Görev

Kolay

Bir kahraman bir ızgarada hareket eder ve her hareket geri alınabilir. Command (command.gd), execute() ve undo() işlevlerini bildirir; Hero (hero.gd) ise x, y ve position_text() içerir. Şunları yaz:

  • MoveCommand: yapıcı, kahramanı ve step_x ile step_y adımlarını saklar. execute(), adımları kahramanın x ve y değerlerine ekler; undo() ise bunları çıkarır.
  • CommandHistory: run(command) komutu çalıştırır ve saklar. undo_last() saklanan en yeni komutu geri alır, onu kaldırır ve true döndürür; saklanan komut yoksa false döndürür.

Verilen kod, ardından kaç eylem geleceğini okur, sonra her satırda bir eylem (up, down, left, right veya undo) okur ve her birinden sonra konumu yazdırır. up, y değerini bir azaltır. right, up, undo, undo, undo için çıktı şöyledir:

right -> (1, 0)
up -> (1, -1)
undo -> (1, 0)
undo -> (0, 0)
Nothing to undo

Kodunu move_command.gd ve command_history.gd dosyalarına yaz. main.gd, verilen girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

extends Node

func _ready():
	# Sağlanan giriş/çıkış kodu: olduğu gibi bırakın
	var hero := Hero.new()
	var history := CommandHistory.new()
	var steps := {"up": [0, -1], "down": [0, 1], "left": [-1, 0], "right": [1, 0]}
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var action := OS.read_string_from_stdin()
		if action == "undo":
			if history.undo_last():
				print("undo -> ", hero.position_text())
			else:
				print("Nothing to undo")
		else:
			var step: Array = steps[action]
			history.run(MoveCommand.new(hero, step[0], step[1]))
			print(action, " -> ", hero.position_text())
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