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

سنوضّح في هذا المقال من سلسلة دليل جودو كيفية برمجة صاروخ موجه ، والذي هو مقذوف يبحث عن هدف متحرك، ، حيث سنستخدم عقدة Area2D لتنفيذ حركة الصاروخ، مع إضافة التأثيرات البصرية مثل الدخان والانفجارات' كما سنوضح كيفية استخدام التسارع والتوجيه الذكي Steering لتحريك الصاروخ نحو الهدف مع التحكم في قوة التوجيه لتحقيق حركة أكثر واقعية؛ كما سنوضح أيضًا كيفية استدعاء الدوال المناسبة للتحكم في وقت حياة الصاروخ، وكيفية تفاعله مع البيئة المحيطة.

ستساعدنا هذه المفاهيم الأساسية على تطوير أنظمة موجهة أخرى في الألعاب التي تتطلب تفاعلًا ديناميكيًا مع الأهداف المتحركة.

برمجة صاروخ موجه للكشف عن الهدف المتحرك

لبرمجة صاروخ موجه، والذي هو مقذوف يبحث عن هدف متحرك، سنستخدم عقدة Area2D للمقذوف؛ إذ تُعَد عقد المناطق Areas خيارات جيدة للرصاصات أو الأجسام المتحركة التي تُطلق من الصاروخ لأننا بحاجة إلى كشفها عند ملامستها لشيء ما، ولكن إذا كنا بحاجة أيضًا إلى رصاصة ترجع أو ترتد، فقد تكون العقد من نوع PhysicsBody خيارًا أفضل.

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

فيما يلي العقد التي سنستخدمها:

Area2D: Missile
    Sprite2D
    CollisionShape2D
    Timer: Lifetime

يمكن استخدام أي صورة نريدها بالنسبة للخامة Texture كما في المثال التالي:

01 missile

يمكن الآن إعداد العقد وضبط خامة الشخصية الرسومية 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
    

يمكن تغيير اتجاه الصاروخ للتحرك نحو الهدف باستخدام التسارع في ذلك الاتجاه، فالتسارع هو تغير في السرعة؛ حيث يريد الصاروخ الحالي التحرك نحو الهدف مباشرةً، ولكن تشير سرعته الحالية إلى اتجاه مختلف، ويمكننا إيجاد هذا الفرق باستخدام الرياضيات الشعاعية كما يلي:

02_steering_diagram ar.png

يمثل السهم الأخضر التغير المطلوب في السرعة، أي التسارع 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.

اقرأ أيضًا


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

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

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



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

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

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

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


×
×
  • أضف...