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

الاتصال بالإشارات

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

تأخذ connect() الدالة التي ستُنفَّذ على هيئة Callable. اكتب اسم الطريقة دون أقواس، أو اكتب دالة لامبدا:

chest.opened.connect(_on_chest_opened)          # دالة تابعة لهذا السكربت
chest.opened.connect(quest_log.add_entry)       # دالة تابعة لكائن آخر
chest.opened.connect(func(): print("Creak!"))   # دالة لامدا

تسمّي Godot دالة الاستماع باستخدام _on_، ثم اسم المُرسِل، ثم الإشارة: _on_chest_opened. يمكن أن تكون للإشارة دوال متصلة عديدة، وتُنفَّذ بالترتيب الذي تم به توصيلها.

عادةً ما يربط الكائن الذي يستمع نفسه، في دالة تستقبل المُصدِر:

# quest_log.gd
class_name QuestLog
extends RefCounted

var chests_opened := 0

func track(chest: Chest) -> void:
	if not chest.opened.is_connected(_on_chest_opened):
		chest.opened.connect(_on_chest_opened)

func untrack(chest: Chest) -> void:
	if chest.opened.is_connected(_on_chest_opened):
		chest.opened.disconnect(_on_chest_opened)

func _on_chest_opened() -> void:
	chests_opened += 1

يُعدّ توصيل الدالة نفسها بالإشارة نفسها مرتين خطأً، وكذلك فصل دالة غير موصولة. تتحقق is_connected() أولًا. يوقف disconnect() الاستماع، ولا يؤدي الإرسال التالي إلى تشغيل تلك الدالة.

مرّر CONNECT_ONE_SHOT بوصفه الوسيط الثاني، وسيُزال الاتصال بعد استدعائه للمرة الأولى: chest.opened.connect(_on_first_open, CONNECT_ONE_SHOT).

تحتفظ دالة lambda بالقيمة التي كان عليها المتغير المحلي عند إنشاء دالة lambda. يغيّر count += 1 داخل دالة lambda متصلة تلك النسخة، ويبقى count في _ready() مساويًا لـ 0. احتفظ بعدّاد في متغير عضو ضمن كائن مستمع، كما يفعل QuestLog.

challenge icon

التحدي

سهل

يحتوي ميدان الرماية على أهداف تُصدر الإشارة hit عند إصابتها. اكتب ScoreBoard الذي يستمع إليها:

  • تربط watch(target) إشارة hit الخاصة بالهدف بالدالة _on_target_hit. لا يؤدي رصد هدف مرصود بالفعل إلى أي تغيير.
  • تفصل ignore(target) الاتصال. لا يؤدي تجاهل هدف غير مرصود إلى أي تغيير.
  • تضيف _on_target_hit() القيمة 10 إلى points وتطبع Hit! Score: N.

يجب ألا يتسبب الرصد مرتين أو تجاهل هدف غير مرصود في حدوث خطأ، لأن أي خطأ يؤدي إلى فشل الاختبار. الملف target.gd مكتمل.

يقرأ الكود المزوّد عدد الأهداف، ثم أوامر مثل watch 0 وignore 0 وshoot 0، ويطبع النتيجة النهائية. بالنسبة إلى هدفين والأوامر watch 0 وshoot 0 وshoot 1 وwatch 1 وwatch 1 وshoot 1 وignore 0 وshoot 0، تكون النتيجة المطبوعة:

Shot target 0
Hit! Score: 10
Shot target 1
Shot target 1
Hit! Score: 20
Shot target 0
Final score: 20

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

جرّب بنفسك

extends Node

func _ready():
	# شيفرة الإدخال والإخراج المقدَّمة: أبقِها كما هي
	var board := ScoreBoard.new()
	var targets: Array[Target] = []
	for i in int(OS.read_string_from_stdin()):
		targets.append(Target.new())
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		var target := targets[int(parts[1])]
		if parts[0] == "watch":
			board.watch(target)
		elif parts[0] == "ignore":
			board.ignore(target)
		else:
			print("Shot target ", parts[1])
			target.shoot()
	print("Final score: ", board.points)
quiz iconاختبر نفسك

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

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

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