اذهب إلى المحتوى

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

إضافة سكريبت إلى اللاعب

يُبنى سلوك الكائنات وآليات اللعب عن طريق كتابة سكريبتات برمجية وإلحاقها بالعقد وبغيرها من الكائنات. وقد رأينا سابقًا كيف يعرض المشهد Player سفينة الفضاء ويُعرّف صندوق التصادم الذي يحيط بها وغيره من الخواص، لكنها لا تستطيع التحرك بعد، ولن يحدث شيء إذا اصطدم بها جسم. لهذا سنكتب شيفرة إضافة هذه الوظائف إلى السفينة.

لفعل ذلك، سنختار العقدة Player ثم ننقر على خيار إلحاق نص برمجي Attach script.

01_adding_script.png

ليس علينا تغيير أي خيارات في نافذة إلحاق نص برمجي للعقدة، بل علينا النقر فقط على زر 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 كما هو موضح بالصورة الآتية:

02 export variable

أما باقي محتوى الشيفرة أعلاه، فيعني:

  • تُستدعى الدالة ()process_ مرةً واحدة من قبل المحرّك عند تنفيذ كل إطار، وتُنفّذ الشيفرة التي تضمها
  • يتحقق التابع ()Input.get_vector من حالة المفاتيح المضغوطة من بين المفاتيح الأربعة المخصصة للإدخال ويولّد شعاع مدخلات له نفس اتجاه الحركة
  • نغيّر أخيرًا موقع السفينة position بإضافة شعاع المدخلات وتعديل قيمته إلى السرعة المطلوبة ثم نضربه بالمعامل delta

سنشغّل المشهد الآن بالنقر على زر Run Current Scene ونحاول تحريك السفينة.

03  playing 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.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...