Menu
CoddyTech
flag Ar iconالعربيةdown icon

الإشارات مع الوسائط

جزء من قسم البرمجة كائنية التوجّه في رحلة GDScript على Coddy. الدرس 38 من 65.

يمكن للإشارة أن تحمل قيمًا. أدرجها في التصريح، مثل معاملات الدالة:

signal damaged(amount: int, hp_left: int)
signal died

مرّر القيم إلى emit() بالترتيب نفسه:

func take_damage(amount: int) -> void:
	hp = maxi(hp - amount, 0)
	damaged.emit(amount, hp)
	if hp == 0:
		died.emit()

تتلقى الدالة المتصلة القيمَ بوصفها معلماتها، لذا تحتاج إلى معلمة لكل قيمة:

hero.damaged.connect(_on_hero_damaged)

func _on_hero_damaged(amount: int, hp_left: int) -> void:
	print("-%d HP, %d left" % [amount, hp_left])

توثّق الأنواع في التصريح القيم: لا يتحقق GDScript منها عند إصدار الإشارة. يظهر عدم التطابق في الدالة المستقبِلة. الدالة التي لديها عدد خاطئ من المعاملات، أو معامل محدد النوع لا يمكنه استيعاب القيمة، تتسبب في خطأ عند سطر emit()، ولا تُشغَّل تلك الدالة.

تضيف bind() قيمًا من اختيارك بعد القيم المُرسَلة. يمكن عندئذٍ لطريقة واحدة الاستماع إلى عدة أبطال ومعرفة من منهم تلقّى الضربة:

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")

تزوّد الوسائط المستمع بالبيانات التي يحتاج إليها، فلا يضطر إلى قراءتها من المُصدِر. لا تربط أبدًا لامبدا تستخدم الكائن المُصدِر نفسه، مثل hero.died.connect(func(): print(hero.hp)): إذ تُبقي اللامبدا hero حيًا، ويُبقي hero اللامبدا، فلا يُحرَّر أيٌّ منهما أبدًا، ويُبلّغ Godot عن وجود نُسخ متسرّبة عند انتهاء البرنامج.

challenge icon

التحدي

سهل

تعرض المحفظة كل تغيير باستخدام إشارات تحمل الأرقام. في Wallet، أضف المعاملات إلى كلتا الإشارتين واكتب الطريقتين:

  • balance_changed(old_balance: int, new_balance: int) وpurchase_failed(price: int, missing: int)
  • add(amount) تضيف العملات وتُصدر balance_changed مع الرصيد قبل التغيير وبعده.
  • buy(price): عندما يكون الرصيد كافيًا، اطرح السعر وأصدر balance_changed. وإلا فلا تغيّر شيئًا، وأصدر purchase_failed مع السعر وعدد العملات الناقصة.

يربط الكود المزوّد دالةً بكل إشارة، ويقرأ عدد الأوامر التالية، وينفّذ كل أمر (add 20، buy 15)، ثم يطبع العملات المتبقية في النهاية. عند تنفيذ add 20، buy 15، buy 10، add 5، buy 10، يطبع:

Balance: 0 -> 20
Balance: 20 -> 5
Cannot buy for 10: 5 coins missing
Balance: 5 -> 10
Balance: 10 -> 0
Coins left: 0

ضع الكود في wallet.gd. يحتوي main.gd على كود الإدخال/الإخراج المزوّد، ولا يمكن تعديله.

جرّب بنفسك

extends Node

func _ready():
	# شيفرة الإدخال/الإخراج المقدَّمة: أبقِها كما هي
	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])
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجّه

تدرّب بنفسك: مترجم GDScript عبر الإنترنت