أعددنا في مقال سابق بيئة اللعبة ثم بنينا في المقال الذي يليه مشهد اللاعب، وسنتابع في هذا المقال الذي هو جزء من سلسلة دليل جودو العمل على لعبتنا ثنائية الأبعاد في محرك الألعاب جودو ونبدأ بكتابة شيفرة سفينة الفضاء التي يتحكم بها اللاعب.
إضافة سكريبت إلى اللاعب
يُبنى سلوك الكائنات وآليات اللعب عن طريق كتابة سكريبتات برمجية وإلحاقها بالعقد وبغيرها من الكائنات. وقد رأينا سابقًا كيف يعرض المشهد Player
سفينة الفضاء ويُعرّف صندوق التصادم الذي يحيط بها وغيره من الخواص، لكنها لا تستطيع التحرك بعد، ولن يحدث شيء إذا اصطدم بها جسم. لهذا سنكتب شيفرة إضافة هذه الوظائف إلى السفينة.
لفعل ذلك، سنختار العقدة Player
ثم ننقر على خيار إلحاق نص برمجي Attach script.
ليس علينا تغيير أي خيارات في نافذة إلحاق نص برمجي للعقدة، بل علينا النقر فقط على زر Attach Node Script، وسينتقل بنا المحرّك إلى محرر السكريبت.
لنلق نظرةً إلى السطر الأول من السكريبت الذي أُضيف تلقائيًا:
extends Area2D
يعرّف هذا السطر نوع الكائن الذي يرتبط به السكريبت، وبالتالي سيكون السكريبت قادرًا على الوصول إلى جميع الوظائف التي تقدمها العقدة Area2D
، ويجب أن يتطابق السطر دائمًا مع نوع العقدة التي تُلحق السكريبت بها.
الوصول إلى السكريبتات
لا يفعّل السكريبت الكثير بمفرده، بل يكتفي بتعريف وظائف إضافية في أي كائن ترتبط به فقط؛ إذ لن نحتاج أبدًا إلى الوصول إلى متغيرات في بعض السكريبتات، بل الوصول إلى خاصيات الكائن التي يُعرّفها السكريبت، وتمييز هذا الأمر مهم جدًا.
تحريك السفينة
سنبدأ الآن بتحريك السفينة حول الشاشة، وسنكتب شيفرة تنفّذ ما يلي:
- التقاط مفاتيح الإدخال التي يضغط عليها اللاعب
- تحريك السفينة في الاتجاه الذي يفرضه مفتاح الدخل
@export var speed = 150 func _process(delta): var input = Input.get_vector("left", "right", "up", "down") position += input * speed * delta
يمكّن التوجيه export@
المضاف قبل اسم المتغير في الشيفرة أعلاه من تعديل قيمته في نافذة الفاحص Inspector كما هو موضح بالصورة الآتية:
أما باقي محتوى الشيفرة أعلاه، فيعني:
-
تُستدعى الدالة
()process_
مرةً واحدة من قبل المحرّك عند تنفيذ كل إطار، وتُنفّذ الشيفرة التي تضمها -
يتحقق التابع
()Input.get_vector
من حالة المفاتيح المضغوطة من بين المفاتيح الأربعة المخصصة للإدخال ويولّد شعاع مدخلات له نفس اتجاه الحركة -
نغيّر أخيرًا موقع السفينة
position
بإضافة شعاع المدخلات وتعديل قيمته إلى السرعة المطلوبة ثم نضربه بالمعاملdelta
سنشغّل المشهد الآن بالنقر على زر Run Current Scene ونحاول تحريك السفينة.
البقاء ضمن الشاشة
حتى الآن، إذا حاولنا الاستمرار في التحرك باتجاه محدد، فستغادر السفية شاشة اللعبة، ولهذا علينا تحديد قيمة الخاصية position
كي تبقى السفينة داخل مربع الشاشة. ولحل هذه المشكلة سنضيف السطر التالي في أعلى السكريبت.
@onready var screensize = get_viewport_rect().size
يخبر التوجيه onready@
جودو ألا يضبط قيمة المتغيّر screensize
حتى تدخل العقدة Player
شجرة المشهد. ويعني ذلك حرفيّا ضرورة الانتظار حتى بداية اللعبة، لعدم وجود نافذة نتحرى أبعادها قبل أم تبدأ اللعبة.
ستكون الخطوة التالية هي حصر موقع السفينة ضمن حدود المربع screensize
باستخدام التابع ()clamp
الذي يضمه الشعاع position
كونه من النوع Vector2
.
func _process(delta): var input = Input.get_vector("left", "right", "up", "down") position += input * speed * delta position = position.clamp(Vector2.ZERO, screensize)
بعدها نشغّل المشهد مجددًا ونحاول أن تحرك السفينة. سنلاحظ كيف تتوقف السفينة عند حواف الشاشة لكن نصفها يغادر الشاشة، وذلك لأن موقع السفينة position
هو في مركزها أي مركز العقدة Sprite2D
. وطالما أن أبعاد السفينة هي 16x16
، فبإمكاننا تغيير مقدار الاقتصاص وزيادة ما مقداره 8 بكسل كالتالي:
position = position.clamp(Vector2(8, 8), screensize - Vector2(8, 8))
ربط الرسم المتحرك بالاتجاه
تتحرك السفية الآن كما هو مطلوب، وبإمكاننا اختيار صور مائلة للسفينة عند التحرك يمينًا أو يسارًا وكذلك صور مائلة للهب كي يعطي الحركة ديناميكية أكبر.
وللتحقق من جهة الحركة، نستطيع التحقق من قيمة x
لشعاع الإدخال input
فيما لو كان موجبًا فيعطي حركة يمينًا، أو سالبًا فيعطي حركة يسارًا، أو صفر بمعنى عدم وجود أي حركة.
والآن، سنطبق التغييرات على الخاصية frame
للعقدة Sprite2D
، وذلك باختيار إطار معين عند الحركة يمينًا أو يسارًا لتغيير شكل صورة السفينة؛ وعلى الخاصية animation
للعقدة AnimatedSprite2D
لتغيير شكل اللهب كما يلي:
func _process(delta): var input = Input.get_vector("left", "right", "up", "down") if input.x > 0: $Ship.frame = 2 $Ship/Boosters.animation = "right" elif input.x < 0: $Ship.frame = 0 $Ship/Boosters.animation = "left" else: $Ship.frame = 1 $Ship/Boosters.animation = "forward" position += input * speed * delta position = position.clamp(Vector2(8, 8), screensize-Vector2(8, 8))
ختامًا
بهذا نكون قد وصلنا إلى نهاية المقال الذي تعرفنا فيه على كيفية كتابة شيفرة التحكم بسفينة الفضاء عبر محرك Godot. يجب التأكد من أن كل شيء يعمل بشكل طبيعي كما هو مطلوب قبل الانتقال إلى الخطوة التالية التي سنشرحها في المقال التالي، والذي سننشئ فيها مشهد الرصاصة ونبرمج عملية إطلاق النار.
ترجمة -وبتصرف- لمقال Coding the Player.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.