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

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

أهمية العقدة RayCast2D في تطوير الألعاب

تمثل العقدة RayCast2D  في محرك ألعاب جودو شعاعًا ينطلق من نقطة الأصل الممثلة بمركز العقدة إلى نقطة نهاية، والشعاع ray هو خط افتراضي ينطلق من نقطة باتجاه زاوية معينة ويمتد في الفضاء، ويمكننا التحقق فيما إذا كان هذا الشعاع قد اصطدم بشيء ما في المشهد أو وصل إلى نهايته دون أي تصادم.

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

أهم خصائص العقدة RayCast2D

تتضمن العقدة RayCast2D في جودو مجموعة من الخصائص المهمة التي تساعدنا على ضبط سلوك الشعاع بشكل دقيق. 

دعونا ننشئ مشروع جديد للعبة ثنائية الأبعاد، ونضيف للمشهد عقدة RayCast2D ونتحقق من خصائصها الظاهرة في الفاحص Inspector كما يلي:

001 kyn raycast2d 01 4

فيما يلي الخاصيات الرئيسية التي ستحتاج إلى فهمها للتعامل مع هذه العقدة:

الخاصية Enabled

تستخدم للتحكم في تفعيل أو تعطيل شعاع RayCast، فعند تفعيل هذه الخاصية، سيبدأ الشعاع في الكشف عن التصادمات مع الأجسام في كل إطار فيزيائي. وإذا ألغينا تفعيلها فسيتعطل عمل كشف تصادم الأشعة.

الخاصية Exclude Parent

عند تفعيل هذه الخاصية، سيتجاهل الشعاع التصادم مع العقدة الأب المباشرة. وتكون هذه الخاصية مفعَّلة افتراضيًا لتجنب الكشف عن تصادمات غير مرغوب بها مع الكائن الذي يحتوي على الشعاع.

الخاصية Target Position

تحدد هذه الخاصية نقطة نهاية الشعاع بالنسبة لموضع العقدة نفسه، أي باستخدام الإحداثيات المحلية، على سبيل المثال، إذا كانت قيمتها (250,0) فسيمتد الشعاع أفقيًا لليمين لمسافة 250 وحدة وهي نقطة الوجهة للشعاع في الإحداثيات المحلية.

ملاحظة: تمثل الإحداثيات المحلية Local Coordinates موقع العقدة بالنسبة لنقطة الأصل الخاصة بالعقدة الأم، بينما تمثل الإحداثيات العامة Global Coordinates الموقع المطلق للعقدة داخل المشهد بأكمله.

لنلاحظ أيضًا القسم بعنوان Collide With ضمن الفاحص، ففي هذا القسم يمكننا تحديد أنواع الكائنات التي يجب أن يتفاعل معها الشعاع، حيث سيكتشف الشعاع افتراضيًا الأجسام الفيزيائية Bodies فقط مثل KinematicBody2D أو RigidBody2D، ولو أردنا منه اكتشاف المناطق أيضًا مثل Area2D فعلينا تفعيل الخيار Area.

دوال مفيدة للعقدة RayCast2D

يمكن الاطلاع على القائمة الكاملة لدوال العقدة RayCast2D في توثيق واجهة برمجة التطبيقات API، ولكن سنوضح تاليًا بعض الدوال المفيدة للتعامل مع التصادمات:

  • is_colliding()‎: دالة منطقية تتيح معرفة فيما إذا كان الشعاع يصطدم بشيء ما
  • get_collision_point()‎: إذا اصطدم الشعاع بشيء ما ستعيد هذه الدالة موضع التصادم في الإحداثيات العامة
  • get_collider()‎: إذا اصطدم الشعاع بشيء ما ستعيد هذه الدالة مرجعًا إلى الكائن المتصادم
  • get_collision_normal()‎: تعيد هذه الدالة الشعاع الناظم Normal على الكائن المتصادم عند نقطة الاصطدام

أمثلة عملية

توجد العديد من الاستخدامات العملية المفيدة لتقنية كشف تصادم الأشعة مثل الرؤية Visibility أي هل يمكن للكائن A أن يرى الكائن B أم أن هناك عائقًا بينهما يحول دون ذلك، والقرب Proximity أي هل اللاعب قريب من جدار أو أرض أو عائق وغير ذلك من الاستخدامات المختلفة.

سنوضح فيما يلي بعض الأمثلة العملية المفيدة.

المثال الأول: إطلاق النار

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

يمثّل الشكل التالي شخصية اللاعب حيث أضفنا عقدة Raycast2D عند نهاية السلاح، وضبطنا موضع الهدف target_position على القيمة (250,0)لضبط اتجاه الشعاع الذي يُطلق من السلاح.

002 kyn raycast2d 02

إذا أطلق اللاعب قذيفة، فيجب التحقق فيما إذا كان الشعاع يصطدم بشيء ما كما يلي:

func _input(event):
    if event.is_action_pressed("shoot"):
        if $RayCast2D.is_colliding():
            print($RayCast2D.get_collider().name)

المثال الثاني: اكتشاف حافة منصة

لنفترض وجود عدو يمشي على منصة ضمن لعبة ما، لكننا لا نريده أن يسقط من حافة هذه المنصة بل نريده أن يرتد ويتحرك في الاتجاه المعاكس، لذا سنضيف إلى العدو عقدتين من النوع Raycast2D كما يلي:

003 kyn raycast2d 03

نتحقق متى سيتوقف الشعاع عن الاصطدام بأي شيء في سكربت العدو من خلال الدالة ()is_colliding، ففي حال أعادت الدالة false، فهذا يعني أننا وجدنا الحافة ويجب علينا الالتفاف:

func _physics_process(delta):
    velocity.y += gravity * delta
    if not $RayRight.is_colliding():
        dir = -1
    if not $RayLeft.is_colliding():
        dir = 1
    velocity.x = dir * speed
    $AnimatedSprite.flip_h = velocity.x > 0
    velocity = move_and_slide(velocity, Vector2.UP)

يعمل الكود أعلاه على تحريك العدو على المنصة مستعينًا بشعاعي Raycast2D للكشف عن الوصول لحافة المنصة، فإذا لم يصطدم الشعاع الأيمن بشيء سيتحرك العدو لليسار، وإذا لم يصطدم الشعاع الأيسر بشيء سيتحرك العدو لليمين.

وسيبدو الأمر أثناء العمل كما يلي:

004 kyn raycast2d 04

الخاتمة

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

ترجمة -وبتصرّف- للقسم RayCast2D من توثيقات Kidscancode.

اقرأ أيضًا


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

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

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



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

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

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

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.


×
×
  • أضف...