انشاء تحريك باستخدام عقدة الـTween في محرك Godot

Godot

من أكثر العقد التي تعجبني في محرك الألعاب غودو هي عقدة الـtween-وسيط، لانك تستطيع استخدامها بسهولة لعمل تحريك او تلاعب بسيط في خصائص العقد الاخرى، وذلك لتكوين تحريك سلس.

والجميل أن العقدة تقوم باعطائك خصائص أخرى مفيدة، مثل مقدار وقت الانتقال من قيمة الى اخرى، او مقدار الوقت قبل بدا الانتقال، بالاضافة الى طريقة بسيطة لتشغيل اكثر من انتقال في نفس الوقت.

في هذا المقال اشرح كيفية استخدام عقدة الوسيط – tween، من أجل عمل تلاعب بسيط في خصائص عقدة اخرى. ولكن وجب التنبيه ان هذا المقال لإصدارات المحرك الأقل من 4، فمن بعد النسخة 4، بدء استخدام طريقة جديدة للتعامل مع هذه التقنية

ولكن دعنا اولا نتعرف على تقنية الوسيط ولما تسمى بهذا الاسم.

ما هي وكيف تعمل

كلمة tween اختصار لكلمة between، والتي تعني “بين شيئين”، تهدف تقنية الـtween الى اضافة مجموعة من القيم بين قيمتين، ويزايد على ذلك هو التحكم في الانتقال بين تلك القيم، هل هو سريع ام بطيء، سريع في البداية ثم بطيء في النهاية أم العكس.

والانتقال بين القيم في الالعاب يكون في شكل إطارات-frames، بالتالي يمكن القول أن التقنية تضيف مجموعة اطارات بين إطارين محددين، فيظهر التحريك او الانتقال بشكل اكثر سلاسة.

هذا الانتقال السلس يكون على شكل منحنى تغير، أي أن قيمة الانتقال من إطار\قيمة الى اخرى لا يكون هو نفسه مثل سابقه

وبما ان التقنية تعمل على اضافة مجموعة من القيم “وسط” قيمتين، فقررت استخدام كلمة “وسيط” للتعبير عنها في هذا المقال.

هكذا تكون قد فهمت الفكرة الاساسية لتقنية الوسيط وكيف تعمل، الآن يمكنك البدء في تجهيز المشروع.

اعداد المشروع

اولا قم بفتح محرك غودو وانشأ مشروعا جديدا. سمه ما تشاء، بعد فتح المشروع، انتقل الى محرر الـ2D

هذا المشروع يمكن أن تستخدمه لعمل تجاربك الخاصة مع عقدة الوسيط، في الوقت الحالي نحن نستخدمه لعمل تحريك بسيط، لذلك اضف العقدة Node كعقدة اساسية، ثم اضف اليها العقدة المسماة بـtween

بعد ذلك قم بوضع أي صورة تريد من أجل عمل التأثيرات عليها. شخصيا قمت باختيار  صورة الكرة التي تراها على اليسار، الآن قم بوضعها داخل ملفات المشروع

g871.png

قم بتحديد عقدة الـ Node، ثم قم بسحب وإفلات الصورة في المحرر كما هو موضح

set a sprite.gif

وستجد انه تم اضافة العقدة سبِرِيت ــ المختصة بعرض الصور ــ الي العقدة node وبنفس اسم الصورة

وبعد ذلك قم بتحديد العقدة node واضف اليها سكربت فارغ تماما، واكتب هذه الاسطر

func _physics_process(delta): 
  if Input.is_action_just_pressed("ui_select"): 
    # هنا مكان الاسطر خاصتنا
  
    pass
  pass

هكذا عند الضغط على مفتاح المسافة-space تبدأ الحركة التي ستقوم بتجهيزها، حاليا قم بحفظ كل شئ عن طريق ctrl + s

معاملات عقدة الوسيط

قبل أن نبدأ في شرح انشاء التحريك، يجب علينا فهم الأوامر الخاصة بعقدة الوسيط، ورغم أنه يوجد العديد من الاوامر، الا ان اغلب عملنا يكون على الأمر interpolate_property، أما بقية الأوامر فيمكنك التعرف عليها من هنا.

والأمر interpolate_property أي (إقحام الخواص)، هو الأمر المسؤول عن وضع الاعدادات والخواص المتعلقة بالتحريك، مثل بداية ونهاية الانتقال او وقت التحريك بشكل عام. فبعد إدخال هذه الخصائص داخل الأمر، يصبح الوسيط جاهزا لإنشاء التحريك المطلوب.

أمر (إقحام الخواص) يحتاج الى 7 معاملات-Parameters من أصل 8 على الاقل، اذكر لك الـ8 معاملات وفائدة كلاً منها.

العقدةالعقدة التي سيعمل عليها الوسيط، تستطيع استخدام أي طريقة للوصول الى تلك العقدة، مثلا self او owner او get_parent او get_node، وذلك تحديداً للعقدة المطلوبة
الخاصيةالخاصية التي يعمل عليها الـtween، وهي أي خاصية لها قيمة عددية، مثل الحجم والموضع وحتى الالوان (الالوان لها قيم عددية)، او حتى متغيرات من انشائك
القيمة الاولىالقيمة الابتدائية للخاصية، وفي الأغلب يمكنك فقط استدعاء الخاصية نفسها للتعبير عن القيمة الابتدائية لها
القيمة النهائيةوهي القيمة التي تريد ان تكون نهاية النتقال، لو اردت ان يبدء من A الى B، فهنا تذكر القيمة B
الوقتوقت الحركة بالثواني، لو كان 0.5، ذلك يعني أن الوسيط سيأخذ نصف ثانية حتى يصل الى B
منحنى التغيروهو سرعة الانتقال عبر القيم، ويوجد منحنيات تغير كثيرة، يمكنك استعمال هذا الموقع للتعرف عليها.
أسلوب التغييرالتغير يمكن أن يكون من بداية المنحنى ويمكن أن يكون من نهايته، ويمكن أن يكون من البداية والنهاية، في الموقع السابق يعبر عن ذلك بـ in و out و in-out، وهو نفسه هنا
التمهلالتمهل لمقدار محدد من الثواني، هكذا يمكنك وضع وقت ما قبل بداية عمل الوسيط، ويظل متوقفاً حتى انتهاء مدة التمهل.

اول تحريك لك

بعد شرح الامر الاساسي الخاص بإنشاء التحريك، تبقى الآن أول انتقال حقيقي لك.

بداخل شرط الضغط على زر المسافة،قم باستدعاء عقدة الوسيط (قم باستدعائها بنفس الاسم الموجود في شجرة المشهد).

من ثم قم باستدعاء الأمر interpolate_property وافتح القوس الخاص بالمعاملات، فيكون هذا شكل السطر عندك.

$Tween.interpolate_property(

ومثلما ذكرت، يحتاج هذا الأمر الى 7 معاملات، واليك قائمة بها مع قيمة كلاً منها، وموزعة بالترتيب من البداية حتى النهاية، ولكن لا تنسى استخدام علامة الفاصلة ( , ) فصلاً للمعاملات

المعاملقيمتهتعليق
العقدة المطلوب التعامل معها$ballاستخدم self في حال كان السكربت على نفس العقدة
الخاصية المطلوب تعديلها“position:y”يجب أن تكون في شكل نص، واستخدم ( : ) للوصول لخواصها
القيم الابتدائية لتسلسل$ball.position.yنبدأ من موضع الكرة الأساسي
القيمة النهائيةupمتغير نتطرق اليه بعد قليل
الوقت0.5نجعله نصف ثانية حتى يكون سريع
منحنى التغيرTRANS_BOUNCEتحريك الكرة وجعلها ترتد كأنها اصطدمت في شيئ
أسلوب التغييرEASE_IN_OUTأنشاء حركة أرجحة، (عودة للخلف ثم ذهاب وعودة)
  • المتغير up
    هو متغير قيمته (موضع الكرة الافقية) + 200 بكسل لأعلى، أي $ball.position.y + 200

بعد كتابة الأسطر، يمكنك استدعاء أمر “ابدأ” Start() من tween حتى يبدأ بالفعل التحريك الذي جهزته، وتكون هذه هي النتيجة النهائية : 

extends Node

func _physics_pracess(delta):
  if Input.is_action_just_pressd(“ui_select):
    
    var up = $ball.position.y + 200 
    
    $Tween.interpolate_property($ball, “position:y”, $ball.position.y, up, 0.5, Tween.TRANS_BOUNCE, Tween.EASE_IN_OUT)
    
    $Tween.start() 
    pass 
  pass
final tween.gif

تجارب وأمثلة أكثر

يمكنك اللعب في العديد من الخواص المختلفة داخل أي عقدة، مثل خاصية الحجم-scale من أجل تغيير حجم الكائن. وتغير بعض الاعدادات الاخرى مثل الوقت ونوعية التأرجح

$Tween.interpolate_property($ball, “scale”, $ball.scale, Vector2(2,2),1, Tween.TRANS_Back, Tween.EASE_OUT)
$Tween.start()
final scale.gif

او من الممكن ان تكون اكثر تعقيدا بجعلها تتبع احداثيات الفأرة عند الضغط بزر الفارة الايسر على اي مكان في الشاشة، وتقوم بالاستدارة حول محورها في نفس وقت تحركها الى موضع الفارة، وهكذا تحصل على حركة بسيطة جميلة.

(تحتاج الي تعريف زر الفارة اولا في إعدادات المشروع عن طريق إعداد خارطة المدخلات input map، بالنسبة لي، فقد عرفتها باسم “left_mouse_button”)

func _physics_process(delta):
  if Input.is_action_just_pressed("left_mouse_button"):
    var pos = get_viewport().get_mouse_position() # موضع الفأرة 
    var rotat = $ball.rotation + 90 # الاستدارة حول محورها 
    $Tween.interpolate_property($ball, "position", $ball.position, pos, 2, Tween.TRANS_BACK, Tween.EASE_IN_OUT) 
    $Tween.interpolate_property($ball, "rotation", $ball.rotation, rotat, 2, Tween.TRANS_BACK, Tween.EASE_IN_OUT) 
    $Tween.start()
    pass
  pass
wow tween.gif

خلاصة

خلاصة القول هو ان الوسيط يهدف الى عمل تحريك او تلاعب سلس بين قيمتين.

وكل ما تطرقنا اليه حتى الان في المقال، ما هو الا اشياء بسيطة يمكن للوسيط فعلها، تم ذكرها هنا بهدف توضيح كيفية عمل العقدة، بينما هذه الامثلة ليست امثلة يمكن استعمالها بشكل واقعي في الالعاب.

ولكن المبدأ هو نفسه. في الاغلب يستخدم الوسيط مع القيم التي تحتاج الى معادلات حسابية، مثل ايجاد مكان الفارة على الشاشة، او تحريك كائن معين بحيث يتجه الى كائن متحرك اخر.

وايضا مع واجهات المستخدم بكثرة، نظرا لان الواجهات يختلف حجمها وموضوعا من شاشة لاخرى، بالتالي من الذكاء استخدامها بهذه الطريقة.

3.5 2 votes
Article Rating
Subscribe
نبّهني عن
guest

0 تعليقات
Inline Feedbacks
View all comments