ورقة GDScript المرجعية
آخر تحديث
الأساسيات والإخراج
يوسّع السكربت نوعًا من العقد، ويستدعي Godot دواله نيابةً عنك.
| العملية | الصياغة |
|---|---|
| ربط السكربت بنوع عقدة | extends Node |
| كود يعمل عند بدء العقدة | func _ready() -> void:
print("Hello, World!") |
| طباعة القيم دون فاصل | print("HP: ", hp) |
| طباعة القيم مفصولة بمسافات | prints("a", "b", 3) |
| تعليق | # This is a comment |
| تعليق توثيقي | ## Shown in the editor's help |
| سلسلة نصية متعددة الأسطر | var text := """Line one
Line two""" |
| الإبلاغ عن خطأ | push_error("Health is negative") |
| الإبلاغ عن تحذير | push_warning("Old save file") |
المتغيرات والثوابت والأنواع
الأنواع اختيارية. أضفها لتحصل على فحوصات المحرر والإكمال التلقائي وكود أسرع.
| العملية | الصياغة |
|---|---|
| متغير (نوع ديناميكي) | var score = 0 |
| متغير بنوع ثابت | var speed: float = 200.0 |
| استنتاج النوع الثابت | var lives := 3 |
| ثابت | const MAX_HP = 100 |
| تعداد (enum) | enum State { IDLE, RUN, JUMP } |
| استخدام قيمة من enum | var state: State = State.IDLE |
| قيم المتجهات والألوان | var pos := Vector2(10, 20)
var tint := Color(1, 0, 0) |
| مرجع كائن فارغ | var target: Node = null |
| التحويل إلى نص أو int أو float | str(42), int("42"), float("3.5") |
| من float إلى int (تُحذف الكسور) | int(3.9) # 3 |
| التحقق من النوع | value is int, node is Sprite2D |
| التحويل إلى نوع (cast) | var sprite := node as Sprite2D |
العوامل
رياضيات مألوفة، مع كلمات إنجليزية للمنطق.
| العملية | الصياغة |
|---|---|
| الجمع والطرح والضرب والقسمة | a + b, a - b, a * b, a / b |
| القسمة الصحيحة (int / int) | 7 / 2 # 3 |
| باقي القسمة | 7 % 3, fmod(7.5, 2.0) |
| الأس | 2 ** 10 # 1024 |
| الإسناد المركّب | x += 1, x -= 1, x *= 2, x /= 2 |
| المقارنة | ==, !=, <, >, <=, >= |
| المنطق | a and b, a or b, not a |
| المنطق (صيغة الرموز) | a && b, a || b, !a |
| if في سطر واحد كتعبير | var label := "win" if score > 10 else "lose" |
| هل العنصر موجود في مجموعة | "sword" in inventory |
| العمليات على مستوى البت | a & b, a | b, a ^ b, ~a, a << 1, a >> 1 |
التحكم في التدفق
تُحدَّد الكتل بالمسافة البادئة كما في Python. يستخدم Godot علامات الجدولة للإزاحة افتراضيًا.
| العملية | الصياغة |
|---|---|
| If وelif وelse | if hp <= 0:
die()
elif hp < 20:
print("Low HP")
else:
print("OK") |
| if في سطر واحد | if hp <= 0: die() |
| حلقة على نطاق | for i in range(5):
print(i) # 0 to 4 |
| نطاق ببداية ونهاية وخطوة | for i in range(10, 0, -2):
print(i) # 10, 8, 6, 4, 2 |
| التكرار n مرة | for i in 3:
print(i) # 0, 1, 2 |
| حلقة على مصفوفة | for item in items:
print(item) |
| متغير حلقة بنوع محدد (Godot 4.2+) | for n: String in names:
print(n.to_upper()) |
| حلقة while | while hp > 0:
hp -= 10 |
| الخروج من الحلقة أو تخطي خطوة | break, continue |
| عنصر نائب لكتلة فارغة | pass |
مطابقة الأنماط (match)
تنفّذ match أول فرع يطابق نمطه. لا يوجد انتقال تلقائي إلى الفرع التالي.
| العملية | الصياغة |
|---|---|
| مطابقة القيم | match state:
State.IDLE:
print("idle")
State.RUN:
print("run") |
| عدة قيم في فرع واحد | match key:
"w", "up":
move_up() |
| الفرع الافتراضي (حرف بدل) | match n:
0:
print("zero")
_:
print("other") |
| ربط القيمة باسم | match cmd:
"quit":
get_tree().quit()
var other:
print("Unknown: ", other) |
| نمط مصفوفة | match pos:
[0, 0]:
print("origin")
[var x, 0]:
print("on the x axis at ", x) |
| مصفوفة بأي ذيل | match args:
["move", ..]:
print("move command") |
| نمط قاموس | match item:
{"type": "coin", "value": var v}:
gold += v |
| شرط باستخدام when (Godot 4.4+) | match score:
var s when s >= 90:
print("A")
var s when s >= 75:
print("B")
_:
print("C") |
الدوال ودوال lambda
الدوال قيم أيضًا: يمكنك تخزينها وتمريرها وربط وسائط بها.
| العملية | الصياغة |
|---|---|
| معاملات وقيمة إرجاع بأنواع محددة | func add(a: int, b: int) -> int:
return a + b |
| بلا قيمة إرجاع | func reset() -> void:
score = 0 |
| وسيط افتراضي | func greet(who := "player") -> void:
print("Hi, ", who) |
| دالة ثابتة (static) | static func double(x: int) -> int:
return x * 2 |
| دالة lambda في سطر واحد | var square := func(x): return x * x |
| استدعاء Callable | square.call(4) # 16 |
| الدالة كقيمة | var on_done := reset
on_done.call() |
| ربط الوسائط | var add_ten := add.bind(10)
print(add_ten.call(5)) # 15 |
| دالة lambda متعددة الأسطر | var greet_all := func(names: Array) -> void:
for n in names:
print("Hi, ", n) |
| انتظار مؤقّت | await get_tree().create_timer(1.0).timeout |
| انتظار روتين مشترك (coroutine) | var data = await fetch_data() |
السلاسل النصية
تُرجع دوال السلاسل النصية سلسلة جديدة ولا تغيّر الأصلية أبدًا.
| العملية | الصياغة |
|---|---|
| التنسيق باستخدام % | "%s has %d HP" % [name, hp] |
| منزلتان عشريتان | "%.2f" % 3.14159 # "3.14" |
| التنسيق بعناصر نائبة مسمّاة | "{a} vs {b}".format({"a": 1, "b": 2}) |
| الدمج باستخدام + | "Score: " + str(score) |
| الطول | text.length() |
| أحرف كبيرة أو صغيرة | text.to_upper(), text.to_lower() |
| التقسيم إلى أجزاء | "a,b,c".split(",") # ["a", "b", "c"] |
| دمج الأجزاء | ", ".join(["a", "b", "c"]) |
| إزالة المسافات من الطرفين | " hi ".strip_edges() # "hi" |
| استبدال نص | text.replace("cat", "dog") |
| إيجاد موضع | text.find("lo") # -1 if missing |
| تبدأ بـ أو تنتهي بـ | text.begins_with("Hi"), text.ends_with("!") |
| سلسلة فرعية | text.substr(0, 5) |
| تحتوي على | "ell" in "Hello" # true |
المصفوفات
تكبر المصفوفات وتصغر. المصفوفة ذات النوع المحدد لا تقبل إلا عناصر من نوعها.
| العملية | الصياغة |
|---|---|
| مصفوفة حرفية (أنواع مختلطة) | var items = [1, "two", 3.0] |
| مصفوفة بنوع محدد | var scores: Array[int] = [10, 20, 30] |
| القراءة بالفهرس (القيمة السالبة تُعدّ من النهاية) | scores[0], scores[-1] |
| الإضافة إلى النهاية | scores.append(40), scores.push_back(40) |
| الإدراج عند فهرس | scores.insert(0, 5) |
| حذف الأخير وإرجاعه | var last = scores.pop_back() |
| الحذف بالقيمة أو بالفهرس | scores.erase(20), scores.remove_at(0) |
| هل تحتوي، فهرس العنصر | scores.has(30), scores.find(30) |
| الطول، التحقق من الفراغ | scores.size(), scores.is_empty() |
| الترتيب | scores.sort() |
| الترتيب بقاعدتك الخاصة | enemies.sort_custom(func(a, b): return a.hp < b.hp) |
| Map | scores.map(func(x): return x * 2) |
| Filter | scores.filter(func(x): return x > 15) |
| Reduce | scores.reduce(func(acc, x): return acc + x, 0) |
| شريحة (دون عنصر النهاية) | scores.slice(1, 3) |
القواميس
أزواج من المفاتيح والقيم. يمكن أن تكون المفاتيح من أي نوع، والسلاسل النصية هي الأكثر شيوعًا.
| العملية | الصياغة |
|---|---|
| قاموس حرفي | var stats = {"hp": 100, "mp": 30} |
| قاموس بأنواع محددة (Godot 4.4+) | var prices: Dictionary[String, int] = {"sword": 50} |
| قراءة مفتاح أو كتابته | stats["hp"], stats["xp"] = 50 |
| القراءة مع قيمة افتراضية | stats.get("luck", 0) |
| هل يوجد مفتاح | stats.has("hp"), "hp" in stats |
| حذف مفتاح | stats.erase("mp") |
| المفاتيح والقيم | stats.keys(), stats.values() |
| عدد العناصر | stats.size() |
| دمج قاموس آخر (true يستبدل القيم الموجودة) | stats.merge({"luck": 5}), stats.merge(bonus, true) |
| حلقة على المفاتيح | for key in stats:
print(key, " = ", stats[key]) |
الأصناف والتعليقات التوضيحية (annotations)
كل سكربت هو صنف. تبدأ التعليقات التوضيحية بـ @.
| العملية | الصياغة |
|---|---|
| إعطاء الصنف اسمًا عامًا | class_name Player
extends CharacterBody2D |
| الباني (constructor) | func _init(start_hp := 100) -> void:
hp = start_hp |
| إنشاء نسخة | var p := Player.new() |
| صنف داخلي | class Item:
var name := ""
var price := 0 |
| استدعاء نسخة الصنف الأب من هذه الدالة | func _ready() -> void:
super()
print("child ready") |
| استدعاء دالة أخرى من الصنف الأب | super.take_damage(10) |
| متغير ثابت (Godot 4.1+) | static var count := 0 |
| الإظهار في Inspector | @export var speed := 300.0 |
| الإظهار مع شريط تمرير ونطاق | @export_range(0, 100) var volume := 50 |
| جلب عقدة فرعية عندما تكون جاهزة | @onready var sprite: Sprite2D = $Sprite2D |
| دالتا الضبط والجلب (setter وgetter) | var hp := 100:
set(value):
hp = clampi(value, 0, 100)
get:
return hp |
| تشغيل السكربت في المحرر | @tool |
الإشارات
الإشارات قيم من الدرجة الأولى: صرّح بها، ثم أطلقها واربطها وانتظرها مباشرة.
| العملية | الصياغة |
|---|---|
| التصريح بإشارة | signal died |
| إشارة بوسائط ذات أنواع محددة | signal health_changed(old_hp: int, new_hp: int) |
| الإطلاق | died.emit() |
| الإطلاق مع وسائط | health_changed.emit(100, 80) |
| الربط بدالة | player.died.connect(_on_player_died) |
| ربط دالة lambda | button.pressed.connect(func(): print("Clicked")) |
| تمرير وسائط إضافية | button.pressed.connect(_on_pressed.bind("start")) |
| التنفيذ مرة واحدة فقط | timer.timeout.connect(_on_timeout, CONNECT_ONE_SHOT) |
| فك الربط | player.died.disconnect(_on_player_died) |
| التحقق من الربط | player.died.is_connected(_on_player_died) |
| انتظار إشارة | await player.died |
العقد ودورة الحياة
دوال الاستدعاء التي يشغّلها Godot على عقدتك، والاستدعاءات التي تجريها على شجرة المشهد.
| العملية | الصياغة |
|---|---|
| إنشاء الكائن (قبل دخول الشجرة) | func _init() -> void:
print("created") |
| العقدة وأبناؤها جاهزون | func _ready() -> void:
print("ready") |
| كل إطار | func _process(delta: float) -> void:
position.x += 100.0 * delta |
| كل خطوة فيزيائية | func _physics_process(delta: float) -> void:
velocity.y += 980.0 * delta
move_and_slide() |
| الإدخال الذي لم تستخدمه الواجهة | func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("jump"):
jump() |
| جلب عقدة بالمسار | get_node("Sprite2D"), $Sprite2D |
| مسار بمسافات، اسم فريد | $"UI/Health Bar", %HealthBar |
| التحقق من إجراء إدخال | Input.is_action_pressed("move_right") |
| إنشاء نسخة من مشهد | var enemy := preload("res://enemy.tscn").instantiate()
add_child(enemy) |
| حذف عقدة بأمان | queue_free() |
| الأب والأبناء | get_parent(), get_children() |
| تغيير المشهد | get_tree().change_scene_to_file("res://main.tscn") |
صياغة GDScript التي تحتاجها أثناء بناء لعبة في Godot، على صفحة واحدة. ورقة GDScript المرجعية هذه مرجع سريع لـ Godot 4: المتغيرات والأنواع الثابتة، والعوامل، والتحكم في التدفق وmatch، والدوال ودوال lambda، والسلاسل النصية، والمصفوفات والقواميس، والأصناف، والإشارات، ودوال الاستدعاء التي يشغّلها Godot على العقد في كل إطار.
كل ما هنا مكتوب بصياغة Godot 4، لذلك سترى @export و@onready وdied.emit() وawait بدلًا من صيغ Godot 3. انسخ ما تحتاجه إلى السكربت الخاص بك، أو جرّب المقاطع مباشرة في playground الخاص بـ GDScript: ضعها داخل _ready() وشغّلها في متصفحك، دون الحاجة إلى تثبيت Godot.
الأسئلة الشائعة حول ورقة GDScript المرجعية
هل ورقة GDScript المرجعية هذه مجانية؟
هل هذه الورقة المرجعية لـ Godot 4 أم Godot 3؟
@export و@onready بدلًا من الكلمتين المفتاحيتين export وonready، وdied.emit() وdied.connect(callable) بدلًا من emit_signal("died") وconnect القائمة على النصوص، وawait بدلًا من yield، وsuper() بدلًا من .method(). الصفوف المعلّمة بـ 4.1+ أو 4.2+ أو 4.4+ تحتاج إلى ذلك الإصدار من Godot على الأقل.ما الفرق بين = و:= في GDScript؟
var x = 5 ينشئ متغيرًا ديناميكيًا يمكنه لاحقًا حمل أي نوع. var x := 5 يستنتج النوع من القيمة (هنا int) ويثبّته، لذا يصبح إسناد سلسلة نصية إليه لاحقًا خطأً. var x: int = 5 يحدد النوع صراحةً. تمنحك الأنواع الثابتة أخطاء في المحرر وإكمالًا تلقائيًا أفضل وكودًا أسرع.كيف تعمل الإشارات في GDScript؟
signal died، وأرسلها عبر died.emit()، واستجب لها من عقدة أخرى عبر player.died.connect(_on_player_died). يمكنك ربط دالة lambda بدلًا من دالة عادية، أو ربط وسائط إضافية عبر .bind()، أو إيقاف دالة مؤقتًا حتى تنطلق الإشارة عبر await player.died.هل تشبه GDScript لغة Python؟
for ... in وif/elif/else وكلمات إنجليزية مثل and وor وnot. لكن GDScript لغة مستقلة صُممت من أجل Godot. فيها أنواع ثابتة اختيارية، وإشارات، وتعليقات توضيحية مثل @export، ووصول مباشر إلى العقد عبر $.هل يمكنني التدرب على GDScript عبر الإنترنت؟
_ready() مرة واحدة. وإذا أردت مسارًا منظمًا، فإن دورة GDScript التفاعلية المجانية من Coddy تأخذك خطوة بخطوة من المتغيرات والدوال إلى الأصناف والإشارات.