Menu
CoddyTech

מהו אות?

חלק מהיחידה תכנות מונחה עצמים במסלול ה-GDScript של Coddy. שיעור 35 מתוך 65.

דברים קורים לאובייקטים בזמן שהמשחק פועל: אוספים מטבע, דלת נפתחת, ה־hp של הגיבור יורד ל־0. חלקים אחרים בתוכנית מגיבים לאירועים האלה: הניקוד עולה, צליל מתנגן, ומסך סיום המשחק מופיע.

אות הוא הודעה שאובייקט שולח כשמשהו קורה לו. האובייקט פולט את האות, וכל פונקציה המחוברת לאות הזה מופעלת:

# coin.gd
class_name Coin
extends RefCounted

signal collected

func collect() -> void:
	print("Coin picked up")
	collected.emit()

signal collected מכריז על האות, ו־collected.emit() שולח אותו. המטבע לא יודע מי מאזין. הקוד שמתעניין במטבעות מחבר אחת מהפונקציות שלו לאות:

# main.gd
func _ready():
	var coin := Coin.new()
	coin.collected.connect(_on_coin_collected)
	coin.collect()
	print("Done")

func _on_coin_collected() -> void:
	print("Score +1")

הפלט הוא Coin picked up, Score +1, Done. פליטה מפעילה את הפונקציות המחוברות מיד, לפני השורה שאחרי emit(). אות שאין לו פונקציות מחוברות אינו עושה דבר כשהוא נפלט.

בלי אות, collect() הייתה צריכה לקרוא בעצמה לקוד הניקוד, כך שכל מטבע היה צריך הפניה ללוח הניקוד. עם אות, המטבע רק מודיע על האירוע, וכל מספר של מאזינים, או אף אחד מהם, יכולים להגיב אליו.

הצמתים של Godot פועלים באותו אופן: צומת Button פולט pressed כשלוחצים עליו, ו-Timer פולט timeout כשנגמר הזמן שלו.

challenge icon

אתגר

קל

תיבת דואר מודיעה על דואר חדש באמצעות אות. Mailbox כבר מצהירה על signal mail_arrived ויש לה מונה letters. כתוב את deliver(kind):

  • כאשר kind הוא "letter", הוסף 1 ל-letters ופלט את mail_arrived.
  • כל סוג אחר (פרסומת, עלון) נזרק: שום דבר לא משתנה ושום דבר לא נפלט.

הקוד שסופק מחבר פונקציה שמדפיסה You've got mail!, ואז קורא כמה שורות מגיעות ומעביר כל אחת מהן. השורה away מנתקת את הפונקציה הזו, ו-home מחברת אותה שוב, כך שמכתב שמגיע בזמן שאתה לא נמצא נספר אך לא מוכרז. עבור השורות letter, ad, away, letter הוא מדפיס:

Delivering: letter
You've got mail!
Delivering: ad
Delivering: letter
Letters: 2

הקוד שלך ייכתב ב-mailbox.gd. הקובץ main.gd מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.

נסו בעצמכם

extends Node

func _ready():
	# קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
	var mailbox := Mailbox.new()
	mailbox.mail_arrived.connect(_on_mail_arrived)
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var line := OS.read_string_from_stdin()
		if line == "away":
			mailbox.mail_arrived.disconnect(_on_mail_arrived)
		elif line == "home":
			mailbox.mail_arrived.connect(_on_mail_arrived)
		else:
			print("Delivering: ", line)
			mailbox.deliver(line)
	print("Letters: ", mailbox.letters)

func _on_mail_arrived() -> void:
	print("You've got mail!")
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר GDScript אונליין