نشرح في مقال اليوم كيفية إضافة ميزة مهمة لأي لعبة بناء على المقال السابق الذي أنشأنا فيه سكربت للعبة بسيطة لتحريك أيقونة جودو Godot في مسارات دائرية، ألا وهي إعطاء التحكم بالحركة للاعب، ولذلك نحتاج لتعديل الكود البرمجي الذي كتبناة في ملف sprite_2d.gd
.
لدينا أداتان رئيسيتان لمعالجة مدخلات اللاعب في جودو هما:
-
دوال رد نداء الدخل المضمّنة في جودو built-in input callbacks، وبالأخص الدالة
_unhandled_input()_
التي تستدعى لمعالجة الأحداث التي لم يتم التعامل معها بواسطة العقد الأخرى والدالة_process()
وهي دالة افتراضية مضمنّة تستدعيها جودو كل مرة يضغط فيها اللاعب على مفتاح وتُستخدم للتفاعل مع الأحداث التي لا تحصل في كل إطار بشكل مستمر مثل الضغط علىSpace
للقفز، راجع استخدام InputEvent للمزيد عن استرجاع استدعاءات المدخلات -
الكائن المتفرّد
Input
، إن الكائنات المتفردة Singelton هي عبارة عن كائنات يمكن الوصول إليها بشكل عام، وتقدم جودو الوصول للعديد منها في السكربتات، إنها الأداة الأفضل لتفقد المدخلات في كل إطار.
سنستخدم الكائنInput
لأننا نريد أن نعرف إذا ما كان يريد اللاعب التحرك أو الدوران في كل إطار.
يجب استخدام المتغير الجديد direction
من أجل الدوران، استبدل السطر rotation += angular_speed * delta
في دالة _process()
بالشيفرة التالية:
بلغة GDScript:
var direction = 0 if Input.is_action_pressed("ui_left"): direction = -1 if Input.is_action_pressed("ui_right"): direction = 1 rotation += angular_speed * direction * delta
بلغة C#:
var direction = 0; if (Input.IsActionPressed("ui_left")) { direction = -1; } if (Input.IsActionPressed("ui_right")) { direction = 1; } Rotation += _angularSpeed * direction * (float)delta;
إن المتغير المحلي direction
هو مُضَاعف multiplier يمثل الاتجاه الذي يريد اللاعب الدوران نحوه وزيادته تضخّم مقدار الدوران، وتمثل القيمة 0
أن اللاعب لم يضغط على مفتاح السهم اليميني أو اليساري، والقيمة 1
تعني أن اللاعب يريد الدوران نحو اليمين، و-1
تعني أنه يريد الدوران نحو اليسار.
يجب التصريح عن مجموعة شروط واستخدام Input
لإنتاج هذه القيم، نبدأ الشرط بالكلمة المفتاحية if
في GDScript وننهيها بنقطتين، ويكون الشرط هو التعبير بين الكلمة المفتاحية ونهاية السطر.
نستدعي Input.is_action_pressed()
للتحقق فيما إذا كان المفتاح مضغوطًا ضمن هذا الإطار، إذ يأخذ التابع سلسلة نصية تمثل المدخلات ويعيد true
إذا كان المفتاح قد ضُغط وإلا يعيد false
.
إن الفعلين المستخدمين سابقًا "uileft" و "uiright" مُعرفين مسبقًا في جودو، إذ يُفعّلان عندما يضغط اللاعب السهمين اليميني واليساري على لوحة المفاتيح أو الزرين اليمين واليسار على قبضة التحكم.
ملاحظة: يمكن مشاهدة وتعديل المدخلات في المشروع الخاص بك بالذهاب إلى "إعدادات المشروع Project settings" والنقر على تبويبة "خريطة الإدخال Input Map". أخيرًا نستخدم direction
كمُضاعف عند تحديث زاوية الدوران rotation
الخاص بالعقدة:
rotation += angular_speed * direction * delta
يجب أن تتحرك الأيقونة عند الضغط على Left
و Right
عند تشغيل المشهد بهذه الشيفرة.
التحرك عند الضغط على Up
نحتاج لتعديل الشيفرة التي تحسب السرعة velocity من أجل التحرك عند الضغط فقط، بدّل السطر الذي يبدأ بـ var velocity
بالشيفرة التالية:
بلغة GDScript:
var velocity = Vector2.ZERO if Input.is_action_pressed("ui_up"): velocity = Vector2.UP.rotated(rotation) * speed
بلغة C#:
var velocity = Vector2.Zero; if (Input.IsActionPressed("ui_up")) { velocity = Vector2.Up.Rotated(Rotation) * _speed; }
هيئنا متجه السرعة velocity
بالقيمة Vector2.ZERO
وهو ثابت مضمّن في نوع Vector
يمثل متجه ثنائي الأبعاد بطول 0.
إذا ضغط اللاعب "ui_up" نحدث قيمة السرعة وتتحرك الشخصية إلى الأمام.
البرنامج الكامل
التالي هو الملف الكامل sprite_2d.gd
كمرجع.
بلغة GDScript:
extends Sprite2D var speed = 400 var angular_speed = PI func _process(delta): var direction = 0 if Input.is_action_pressed("ui_left"): direction = -1 if Input.is_action_pressed("ui_right"): direction = 1 rotation += angular_speed * direction * delta var velocity = Vector2.ZERO if Input.is_action_pressed("ui_up"): velocity = Vector2.UP.rotated(rotation) * speed position += velocity * delta
بلغة C#:
using Godot; public partial class MySprite2D : Sprite2D { private float _speed = 400; private float _angularSpeed = Mathf.Pi; public override void _Process(double delta) { var direction = 0; if (Input.IsActionPressed("ui_left")) { direction = -1; } if (Input.IsActionPressed("ui_right")) { direction = 1; } Rotation += _angularSpeed * direction * (float)delta; var velocity = Vector2.Zero; if (Input.IsActionPressed("ui_up")) { velocity = Vector2.Up.Rotated(Rotation) * _speed; } Position += velocity * (float)delta; } }
تستطيع الآن الدوران باستخدام الأسهم يمين ويسار والتحرك للأمام عن طريق ضغط Up
إذا شغّلت المشهد.
الخلاصة
يمثل كل برنامج نصي في جودو صنفًا ويتوسع في الأصناف المضمّنة، إن أنواع العقد التي ترث منها الأصناف الخاص بك تعطيك وصولًا إلى خاصيًات مثل rotation
و position
كما في حالتنا، ويمكن أيضًا وراثة العديد من الدوال التي لم تُذكر في هذا المثال.
إن المتغيرات التي تضعها في أول الملف بلغة GDScript هي خاصيات الصنف، التي تدعى متغيرات الأعضاء، ويمكن تعريف الدوال التي ستكون في أغلب الأحوال دوال الأصناف الخاصة بك.
تقدم جودو العديد من التوابع الافتراضية التي يمكن تعريفها لتتصل مع الأصناف الخاصة بك مع المحرك، وتضم الدالة_process()
لتطبيق التغييرات للعقدة في كل إطار، والدالة unhandled_input()_
لاستقبال المدخلات مثل ضغط المفاتيح أو الأزرار من المستخدم، وهناك المزيد أيضًا. كما يسمح الصنف المتفرد Input
بالتفاعل مع إدخالات اللاعب في أي مكان من الشيفرة الخاصة بك، وستستخدمها بالتحديد في حلقة process()_
سنتعلم في الدرس التالي مفهوم الإشارات signals في محرك جودو، وتتمكن من بناء علاقات بين البرامج النصية والعقد عن طريق تشغيل العقد للشيفرات في السكريبتات بشكل يجعل الكود أكثر تنظيمًا وأسهل في الصيانة.
ترجمة - وبتصرف - لقسم Listening to player input من توثيق جودو الرسمي.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.