צמתים כרכיבים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-GDScript של Coddy. שיעור 42 מתוך 65.
לצומת Node יכולים להיות צמתים ילדים. Godot בונה אובייקטים במשחק כך: צומת של גיבור מקבל צומת ילד אחד לכל יכולת, כגון בריאות או תנועה. כל ילד הוא רכיב: צומת קטן שמבצע משימה אחת.
# health.gd
class_name Health
extends Node
var hp := 10
func _ready() -> void:
print("Health ready")
# hero.gd
class_name Hero
extends Node
func _init() -> void:
var health := Health.new()
health.name = "Health"
add_child(health)
func _ready() -> void:
print("Hero ready, hp: ", $Health.hp)add_child() מצרפת צומת כצאצא. תנו לכל רכיב name: get_node("Health"), או הצורה המקוצרת שלו $Health, מוצאת את הצאצא לפי השם הזה. צומת ללא שם, או ששם הצומת שלו תפוס על ידי אח, מקבל שם אוטומטי כגון @Node@4.
הפעולה _ready() של צומת פועלת כשהוא נכנס לעץ הסצנה, עץ הצמתים שהמשחק מריץ. main.gd נמצא בעץ, ולכן הוספת הגיבור אליו מפעילה את שתי המתודות _ready(), תחילה של הצאצא:
# main.gd
var hero := Hero.new()
add_child(hero) # Health מוכן, ואז Hero מוכן, hp: 10
print(hero.get_child_count()) # 1צומת אב ניגש לרכיבים שלו באמצעות get_children() (מערך של הצמתים הילדים, לפי סדר הוספתם), get_child_count() ו-has_node("Health"). הצמתים בעץ משתחררים יחד עם העץ כשהמשחק מסתיים, ולכן רכיב שנוסף באמצעות add_child() אינו דורש ניקוי.
אתגר
קלבנו רובוט מצומתי רכיבים.
Partיורשת מ־Node. הבנאי שלה מקבל שם של חלק וערך עוצמה: הוא שומר את העוצמה ומגדיר אתnameשל הצומת כשם החלק. כאשר חלק נכנס לעץ הסצנה,_ready()שלה מדפיסהLaser attached.Robotיורשת מ־Node.add_part(part_name, power)מוסיפהPartחדשה כצאצא. אם כבר יש לרובוט צאצא בשם הזה, היא מדפיסהLaser is already attachedולא יוצרת דבר.total_power()מחזירה את סכום העוצמה של כל החלקים שלה.
הקוד שסופק מוסיף את הרובוט לעץ הסצנה, קורא כמה פקודות מופיעות בהמשך (add Laser 5, power), ומדפיס את מספר החלקים בסוף. עבור add Laser 5, add Wheels 2, power, add Laser 9, add Arm 3, power הוא מדפיס:
Laser attached
Wheels attached
Total power: 7
Laser is already attached
Arm attached
Total power: 10
Parts: 3כתבו את הקוד שלכם ב־part.gd וב־robot.gd. הקובץ main.gd מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.
נסו בעצמכם
extends Node
func _ready():
# קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
var robot := Robot.new()
add_child(robot)
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
if parts[0] == "add":
robot.add_part(parts[1], int(parts[2]))
else:
print("Total power: ", robot.total_power())
print("Parts: ", robot.get_child_count())
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים
קבצים חיצונייםמבוא ל-OOPמחלקות לעומת אובייקטיםמילת המפתח selfמתודותמאפייניםבנאי (_init)חזרה – מחשבון פשוט2מאפייני מחלקה
משתני מופע לעומת משתנים סטטייםפונקציות סטטיותקובעי מאפייניםמאחזרי מאפייניםפרטיים לפי מוסכמהסיכום – מנהל חשבון בנק5כימוס
איברים ציבוריים ופרטייםאימות באמצעות Settersהסתרת מידעמאפיינים לקריאה בלבדסיכום – מערכת לניהול רשומות תלמידים8מושגי OOP מתקדמים
קומפוזיציה לעומת ירושהמחלקות פנימיותצמתים כרכיביםRefCounted לעומת NodeEnum במחלקותתרגלו בעצמכם: קומפיילר GDScript אונליין