سنتعرف في مقال اليوم على العقدة RayCast2D في محرك جودو وكيفية استخدامها بكفاءة في تطوير الألعاب ثنائية الأبعاد، من أجل كشف تصادم الأشعة Raycasting الذي يفيدنا في العديد من حالات الاستخدام.
أهمية العقدة RayCast2D في تطوير الألعاب
تمثل العقدة RayCast2D
في محرك ألعاب جودو شعاعًا ينطلق من نقطة الأصل الممثلة بمركز العقدة إلى نقطة نهاية، والشعاع ray هو خط افتراضي ينطلق من نقطة باتجاه زاوية معينة ويمتد في الفضاء، ويمكننا التحقق فيما إذا كان هذا الشعاع قد اصطدم بشيء ما في المشهد أو وصل إلى نهايته دون أي تصادم.
تعد هذه التقنية أساسية في العديد من أنواع الألعاب، مثل ألعاب التصويب أو ألعاب المنصات، حيث يمكن استخدامها للكشف الاصطدامات collisions بين الكائنات أو الأسطح، كأن نحتاج لمعرفة إذا كان اللاعب يرى العدو أو إذا كان يلمس الأرضية أم لا، كما يمكن أن نتحقق من خلالها فيما إذا كانت القذيفة التي أطلقناها قد أصابت هدفًا معينًا.
أهم خصائص العقدة RayCast2D
تتضمن العقدة RayCast2D
في جودو مجموعة من الخصائص المهمة التي تساعدنا على ضبط سلوك الشعاع بشكل دقيق.
دعونا ننشئ مشروع جديد للعبة ثنائية الأبعاد، ونضيف للمشهد عقدة RayCast2D
ونتحقق من خصائصها الظاهرة في الفاحص Inspector كما يلي:
فيما يلي الخاصيات الرئيسية التي ستحتاج إلى فهمها للتعامل مع هذه العقدة:
الخاصية 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)
لضبط اتجاه الشعاع الذي يُطلق من السلاح.
إذا أطلق اللاعب قذيفة، فيجب التحقق فيما إذا كان الشعاع يصطدم بشيء ما كما يلي:
func _input(event): if event.is_action_pressed("shoot"): if $RayCast2D.is_colliding(): print($RayCast2D.get_collider().name)
المثال الثاني: اكتشاف حافة منصة
لنفترض وجود عدو يمشي على منصة ضمن لعبة ما، لكننا لا نريده أن يسقط من حافة هذه المنصة بل نريده أن يرتد ويتحرك في الاتجاه المعاكس، لذا سنضيف إلى العدو عقدتين من النوع Raycast2D
كما يلي:
نتحقق متى سيتوقف الشعاع عن الاصطدام بأي شيء في سكربت العدو من خلال الدالة ()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
للكشف عن الوصول لحافة المنصة، فإذا لم يصطدم الشعاع الأيمن بشيء سيتحرك العدو لليسار، وإذا لم يصطدم الشعاع الأيسر بشيء سيتحرك العدو لليمين.
وسيبدو الأمر أثناء العمل كما يلي:
الخاتمة
نحتاج إلى تنفيذ تقنيات كشف التصادم في معظم أنواع الألعاب، لذا من الضروي أن نفهم جيدًا كيفية إعداد واستخدام العقدة RayCast2D
في جودو ونوظفها بشكل صحيح لحل مشكلات شائعة في تطوير الألعاب مثل التصويب واكتشاف حواف المنصات وتجنب العوائق وغيرها من الحالات.
ترجمة -وبتصرّف- للقسم RayCast2D من توثيقات Kidscancode.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.