سنوضّح في هذا المقال من سلسلة دليل جودو كيفية برمجة صاروخ موجه ، والذي هو مقذوف يبحث عن هدف متحرك، ، حيث سنستخدم عقدة Area2D
لتنفيذ حركة الصاروخ، مع إضافة التأثيرات البصرية مثل الدخان والانفجارات' كما سنوضح كيفية استخدام التسارع والتوجيه الذكي Steering لتحريك الصاروخ نحو الهدف مع التحكم في قوة التوجيه لتحقيق حركة أكثر واقعية؛ كما سنوضح أيضًا كيفية استدعاء الدوال المناسبة للتحكم في وقت حياة الصاروخ، وكيفية تفاعله مع البيئة المحيطة.
ستساعدنا هذه المفاهيم الأساسية على تطوير أنظمة موجهة أخرى في الألعاب التي تتطلب تفاعلًا ديناميكيًا مع الأهداف المتحركة.
برمجة صاروخ موجه للكشف عن الهدف المتحرك
لبرمجة صاروخ موجه، والذي هو مقذوف يبحث عن هدف متحرك، سنستخدم عقدة Area2D
للمقذوف؛ إذ تُعَد عقد المناطق Areas خيارات جيدة للرصاصات أو الأجسام المتحركة التي تُطلق من الصاروخ لأننا بحاجة إلى كشفها عند ملامستها لشيء ما، ولكن إذا كنا بحاجة أيضًا إلى رصاصة ترجع أو ترتد، فقد تكون العقد من نوع PhysicsBody
خيارًا أفضل.
يتشابه إعداد العقدة وسلوك الصاروخ مع الإعداد الذي نستخدمه مع الرصاصات العادية، لذا في حال كنا قد أنشأنا مسبقًا عدة أنواع من الرصاص، فيمكننا استخدام الوراثة لإعداد جميع مقذوفاتنا استنادًا على الإعداد الأساسي نفسه.
فيما يلي العقد التي سنستخدمها:
Area2D: Missile Sprite2D CollisionShape2D Timer: Lifetime
يمكن استخدام أي صورة نريدها بالنسبة للخامة Texture كما في المثال التالي:
يمكن الآن إعداد العقد وضبط خامة الشخصية الرسومية Sprite وشكل التصادم، مع التأكّد من تدوير عقدة Sprite2D
بمقدار 90 درجة، بحيث تشير إلى اليمين، مع التأكد من أنها تتطابق مع الاتجاه الأمامي للعقدة الأب.
سنضيف سكربتًا ونتصل بالإشارة body_entered
الخاصة بالعقدة Area2D
والإشارة timeout
الخاصة بالعقدة Timer
كما يلي:
extends Area2D export var speed = 350 var velocity = Vector2.ZERO var acceleration = Vector2.ZERO func start(_transform): global_transform = _transform velocity = transform.x * speed func _physics_process(delta): velocity += acceleration * delta velocity = velocity.clamped(speed) rotation = velocity.angle() position += velocity * delta func _on_Missile_body_entered(body): queue_free() func _on_Lifetime_timeout(): queue_free()
سيؤدي هذا إلى إنشاء صاروخ يتحرك في خط مستقيم عند إطلاقه، ويمكن استخدام هذا المقذوف من خلال إنشاء نسخة منه واستدعاء التابع start()
الخاص به مع التحويل Transform2D
المطلوب لضبط موضعه واتجاهه.
سنستخدم التسارع acceleration
لتغيير السلوك للبحث عن الهدف، ولكن لا نريد أن يدور الصاروخ بسرعة كبيرة، لذا سنضيف متغيرًا للتحكم في قوة التوجيه Steering، مما يعطي الصاروخ نصفَ قطر دوران يمكن تعديله مع سلوك مختلف.
سنحتاج أيضًا إلى متغير الهدف target
حتى يعرف الصاروخ ما الذي يطارده، وسنضعه في التابع start()
كما يلي:
export var steer_force = 50.0 var target = null func start(_transform, _target): target = _target …
يمكن تغيير اتجاه الصاروخ للتحرك نحو الهدف باستخدام التسارع في ذلك الاتجاه، فالتسارع هو تغير في السرعة؛ حيث يريد الصاروخ الحالي التحرك نحو الهدف مباشرةً، ولكن تشير سرعته الحالية إلى اتجاه مختلف، ويمكننا إيجاد هذا الفرق باستخدام الرياضيات الشعاعية كما يلي:
يمثل السهم الأخضر التغير المطلوب في السرعة، أي التسارع acceleration
، ولكن إذا انعطفنا مباشرةً، فسيبدو الأمر غير طبيعي، لذا يجب أن يكون طول متجه التوجيه محدودًا، وهذا سبب استخدام المتغير steer_force
.
تحسب الدالة التالية هذا التسارع، ويمكننا ملاحظة أنه لن يكون هناك توجيه عند عدم وجود هدف، لذا سيواصل الصاروخ التحرك في خط مستقيم.
func seek(): var steer = Vector2.ZERO if target: var desired = (target.position - position).normalized() * speed steer = (desired - velocity).normalized() * steer_force return steer
أخيرًا، يجب تطبيق قوة التوجيه الناتجة في الدالة _physics_process()
كما يلي:
func _physics_process(delta): acceleration += seek() velocity += acceleration * delta velocity = velocity.clamped(speed) rotation = velocity.angle() position += velocity * delta
فيما يلي مثال عن النتائج مع بعض التأثيرات البصرية الإضافية مثل دخان الجسيمات والانفجارات:
الكود الكامل للصاروخ الموجه مع التأثيرات البصرية
فيما يلي السكربت الكامل الذي يضيف سلوك الصاروخ الموجه باستخدام Area2D
للكشف عن الهدف، ويشمل أيضًا التأثيرات البصرية، مثل الانفجارات ودخان الجسيمات عند الاصطدام أو انتهاء الوقت.
extends Area2D export var speed = 350 export var steer_force = 50.0 var velocity = Vector2.ZERO var acceleration = Vector2.ZERO var target = null func start(_transform, _target): global_transform = _transform rotation += rand_range(-0.09, 0.09) velocity = transform.x * speed target = _target func seek(): var steer = Vector2.ZERO if target: var desired = (target.position - position).normalized() * speed steer = (desired - velocity).normalized() * steer_force return steer func _physics_process(delta): acceleration += seek() velocity += acceleration * delta velocity = velocity.clamped(speed) rotation = velocity.angle() position += velocity * delta func _on_Missile_body_entered(body): explode() func _on_Lifetime_timeout(): explode() func explode(): $Particles2D.emitting = false set_physics_process(false) $AnimationPlayer.play("explode") await $AnimationPlayer.animation_finished queue_free()
الخاتمة
بهذا نكون قد وصلنا لنهاية مقالنا الذي تعلمنا كيفية برمجة صاروخ موجه في محرك الألعاب جودو Godot مع تطبيق التسارع والتوجيه الذكي لجعل الصاروخ يتبع هدفًا متحركًا' كما استعرضنا كيفية إضافة تأثيرات بصرية مثل الانفجارات والدخان عند الاصطدام أو انتهاء الوقت.
يمكن تجربة تطبيق هذه الأساليب لتطوير أي ألعاب فيها أعداء يتبعون اللاعب، إذ يتغير سلوك الأعداء بناءً على موقع اللاعب وحركته.
ترجمة -وبتصرّف- للقسم Homing missile من توثيقات Kidscancode.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.