في نهاية الدرس السابق انشأنا ملف نص برمجي وارفقناه بالعقدة الرئيسية الخاصة باللاعب
هذا الملف هو الذي نستطيع فيه كتابة الاكواد البرمجية لنستطيع التحكم باللاعب كما سنبين في هذا الدرس
في اول سطر فيه سنلاحظ وجود extends KinematicBody2D
اي ان هذه العقدة تحتوي خواص صنف الـ KinematcBody2D Class
اي اننا نستطيع ان نستخدم الدوال والمتغيرات والخواص التى سيعطيها لنا هذا الصنف
كما قلنا ان لكل عقدة خواصها المميزة التى تقوم بالغرض الذي أُنشِئت لها
ثم لدينا دالة الـ ready
وكما نعرف انها أحد الدوال الرئيسية التى يبدأ البرنامج بالقراءة من عندها وتنفذ مرة واحدة فقط
عندما كتبنا داخل الدالة print("Hello")
ثم بدأنا تشغيل المشروع او اللعبة
نلاحظ طباعة الكلمة، بمعنى ان البرنامج بدأ التنفيذ من دالة الـ ready
الـ physics_process
مثلها مثل دالة الـ ready
اي انها أحد الدوال الرئيسية التى يبدأ البرنامج بالقراءة من عندها
لكن يتم تنفيذها عدة مرات
وليس مرة واحدة فقط
كما نلاحظ انه عند تشغيل اللعبة تم طباعة الكلمة عدة مرات ويتم تنفيذها دائما طوال تشغيل البرنامج
عندما نتحدث على السرعة فيجب ان نتحدث عن الـ delta
وهي سرعة التى يتم فيها تنفيذ الإطارات frames
اي السرعة ما بين الإطار الحالي والإطار للثالى
بالنسبة لتغير السرعة فلدينا هنا دالتنين متشابهتين وهما
_physics_process(delta), _process(delta)
اختلافهم واضح في الصورة التالية
في دالة الـ physics_process
تكون الـ delta
ثابتة
في دالة الـ process
تكون الـ delta
متغيرة
ما سبب التغير واي دالة نستخدم ؟
-
_process(delta)
- قيمتة متغيره لانه يعتمد على امكانيات الجهاز اي انه يختلف من جهاز لآخر
- لا ينصح استخدامه دائما في كل شيء
-
_physics_process(delta)
- قيمتة ثابتة دائما على كل الاجهزة
- ينصح باستخدامه دائما لكي تكون سرعة اللعبة ثابتة على جميع الاجهزة
هل معنى هذا اننا لا يجب ان نستهدم الـ process
؟
لا نحن نستطيع لكن في حالات معينة لكي نستطيع ان نستخدم كل امكانيات الجهاو ونحافظ على سرعة الثابتة، سنعرف كيف في الدروس القادمة
نحن حاليًا سنستحدم _physics_process(delta)
هناك مشكلة علينا الانتباه لها ستلاحظ هنا ان العقدة الرئيسية الخاصة باللاعب احداثياتها هي (0 ,0)
وعقدة الشكل sprite
احداثياتها (200 ,500)
وهذا الامر خطأ كيف لللاعب ان يكون في مكان وشكله في مكان اخر تماما
لذا سنرجع الشكل الى نقطة الاصل مع اللاعب
سنلاحظ انه بعد ان ارجعنا شكله الى نقطة الاصل ثم حاولنا تحريك اللاعب
سنجد ان الشكل sprite
هو الذي يتحرك وليس اللاعب ككل
لنحل هذه المشكلة نرجع الشكل الى نقطة الاصل ثم نختار عقدة اللاعب الرئيسية
سنجد خيار في شريط الخواص في الاعلى على شكل مربعين
نضغط عليه، ما يقوم به هذا الخيار هو انه يمنعك من تحريك العقد التى تندرج تحت العقدة الرئيسية
بالتالي عندما تحرك العقدة الرئيسية فسيتم تحريكها كاملها هي والعقد التى تندرج تحتها
الأن سنتكلم عن الإحداثيات position
سنجد اننا لدينا keyword
كلمة رئيسية بهذا الاسم
وعندما نطبعها ستعطينا احداثيات العقدة المرفوقة بالنص البرمجي script
الذي نكتب فيه الان
ايضًا نستطيع الوصول الى اي احداثي نريده سواء x
او y
عن طريق كتابة position.x
وposition.y
قبل ان نكمل علينا ان نتكلم عن نوع جديد ومهم من انواع البيانات وهو Vector2
وهو بكل بساطة يسمح لنا بتخزين قيمتين من نوع float
var p := Vector2()
p.x = 200
p.y = 100
print(p) # it will print (200, 100)
الـ Vector2
بداخله الكثير من العناصر مثل x
و y
و abs
لإجاد القيمة المطلقة بين x
وy
يمكنك ان تتفقد عناصره وتعرف خواصه في الـ docs
الخاص بالمحرك
Help => Search
ثم تبحث عن Vector2
لا يمكنك فعل هذا p += 50
لان الـ50
من النوع int
وهو لا يتوافق مع النوع Vector2
والصحيح ان تزود بنفس نوع البيانات هكذا p += Vector2(50, 50)
var p := Vector2()
p.x = 200
p.y = 100
p += 50 # Error
p += Vector2(50, 50) # Correct
بالتالي نستنتج ان position
من النوع Vector2
ان اردت ان تعرف اي معلومات عنها او عن اي شيء اجعل الفأرة عليها ثم اضغط Ctrl + Click
سيتم نقله الى صفحة ال docs
الخاصة به كما ما هو موضح بالصورة التالية
حسنًا نحن كنا نزود على الاحداثيات الخاصة باللاعب في دالة الـ ready
ونحن نعرف انه هكذا سيتم تنفيذ الاوامر مرة واحدة فقط
لكن ماذا ان كتبنا نفس الامر في دالة الـ physics_process
هكذا نستطيع حرفيا ان نحرك اللاعب بتغير احداثياته كما هو موضح في الصورة
من الامور التى يجب ان تنتبه لها جيدًا ان احداثي الـ y
معكوس
بمعنى ان الموجب في الاسفل والسالب في الاعلى
واحداثي الـ x
طبيعي لم يتغير، اي ان الموجب في اليمين والسالب في اليسار
الان نريد ان نتحكم بحركة اللاعب بانفسنا، نضعك على اسهم لوح المفاتيح ونحركه
لنفكر ماذا نريد ان نفعل، نحن نريد انه إذا نضغطتنا على زر السهم الايمن يتحرك اللاعب الى اليمين
الأمر اشبه بـ
if Input is right arrow :
then move the player to right
لدينا صنف جاهز built-in class
يقوم بهذا الواجد وهو Input
هو هو اسم الصنف
بداخله دوال وعناصر ستساعدنا في معرفة اي زر ضغطه اللاعب
منها دالة تدعى is_action_pressed
وهي دالة اسمها عبارة عن سؤال يوضح ما وظيفتها
هذه الدالة قد لاحظت انها تاخذ متغير من النوع جملة string
كما هو موضح في الصورة هناك العديد من الازرار الرئيسية، نحن اخترنا ما يرمز لليمين كما ترى
الدالة ترجع قيمة boolean
بمعنى انه عندما يتم الضغط على الزر المحدد سيرجع لنا true
وعندما لا يتم الضغط سيعطي false
ثم سيتم استقبال قيمة ال boolean
في الشرط if
ويتم تنفيذ الاسطر التى تحت ال if
هناك 3 دوال متشابهه عليك ان تفرق بينهم جيدًا وهم
is_action_pressed("ui_right")
is_action_just_pressed("ui_right")
is_action_just_released("ui_right")
-
is_action_pressed()
- يعطي
true
طالما مازال الزر مضغوطًا
- يعطي
-
is_action_just_pressed()
- يعطي
true
عند لحظة الضغط فقط
- يعطي
-
is_action_just_released()
- يعطي
true
عند لحظة انتهاء الضغط
- يعطي
عندما تدخل الى ال docs
الخاص بصنف Input
ستجد العديد من الدوال، منها ..
حسنا لنجعل اللاعب يتحرك في الاتجهات الاربعة مثل ما فعلنا مع اتجاه اليمين سنفعل مع الباقي
احداثي الـy
معكوس، الموجب في الاسفل والسالب في الاعلى
func _physics_process(delta):
# Move Right +x
if Input.is_action_pressed("ui_right"):
position.x += 1
# Move Left -x
if Input.is_action_pressed("ui_left"):
position.x -= 1
# Move Up -y
if Input.is_action_pressed("ui_up"):
position.y -= 1
# Move Down +y
if Input.is_action_pressed("ui_down"):
position.y += 1
ستلاحظ ايضًا اننا نستطيع ان نتحرك في الزواية مع الضغط على زرين في آن واحد
بالطبع لا، هناك حل بسيط وهو اننا ننشئ متغير فاليكن اسمه speed
اسم يعبر عن وظيفته وهي تخزين سرعة اللاعب
ثم نسند المتغير speed
للاتجاهات الاربعة وكلما اردنا تغير السرعة نقوم فقط بتغير هذا المتغير
var speed = 2
func _physics_process(delta):
# Move Right +x
if Input.is_action_pressed("ui_right"):
position.x += speed
# Move Left -x
if Input.is_action_pressed("ui_left"):
position.x -= speed
# Move Up -y
if Input.is_action_pressed("ui_up"):
position.y -= speed
# Move Down +y
if Input.is_action_pressed("ui_down"):
position.y += speed
حسنا هذا جيد، لكن يبقى شيءٌ اخيرٌ هنا تتذكرون delta
انها سرعة الاطارات frames
اي اننا ان ضربناها في السرعة سيجعل سرعة اللاعب تتوافق مع سرعة الاطارت والجهاز
وفوق هذا سيجعل حركة اللاعب سلسلة اكثر لذا كل ما سنفعله اننا سنضربه في السرعة
وبما ان قيمته كسرية لا تتعدى الواحد صحيح علينا زيادة قيمة ال speed
var speed = 300
func _physics_process(delta):
# Move Right +x
if Input.is_action_pressed("ui_right"):
position.x += speed * delta
# Move Left -x
if Input.is_action_pressed("ui_left"):
position.x -= speed * delta
# Move Up -y
if Input.is_action_pressed("ui_up"):
position.y -= speed * delta
# Move Down +y
if Input.is_action_pressed("ui_down"):
position.y += speed * delta
حسنًا هذا كل ما لدي في هذا الدرس، في الدوس القادم سنتعلم كيف نحسن السرعة بإذن الله