Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Programming

استخدام عزم الدوران والدفاعات لتحريك وتدوير مركبة فضائية مصممة

by
Difficulty:IntermediateLength:MediumLanguages:

Arabic (العربية/عربي) translation by Aisy Abdullah (you can also view the original English article)

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

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

تتم كتابة العرض التوضيحي في Haxe ، ولكن يمكن تطبيق الحل بسهولة بأي لغة. يفترض وجود محرك فيزيائي مشابه لـ Box2D أو Nape ، ولكن أي محرك يوفر الوسائل اللازمة لتطبيق القوى والدوافع والاستعلام عن الخصائص الفيزيائية للهيئات سوف يفعل.

جرب التجريبي

انقر فوق SWF لمنحها التركيز ، ثم استخدم مفاتيح الأسهم ومفاتيح Q و W لتنشيط أجهزة الدفع المختلفة. يمكنك التبديل إلى تصميمات مختلفة لسفن الفضاء باستخدام مفاتيح الأرقام من 1 إلى 4 ، ويمكنك النقر فوق أي كتلة أو دحرجة لإزالتها من السفينة.


تمثل السفينة

يعرض هذا الرسم البياني الفئات التي تمثل السفينة ، وكيف ترتبط ببعضها البعض:

Gamedev Maths and Physics: Using Torque and Thrusters to Correctly Maneuver a Player-Designed Spaceship

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

فئة السفينة هي حاوية من الوحدات. يدير هيكل السفينة ويتعامل مع إرفاق وفصل الوحدات. أنه يحتوي على مثيل ModuleManager واحد.

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

يختلف فصل الوحدات إلى حد ما: لا يزال يتم حذف الشكل والعرض من BodySprite ، ولكن يتم إرفاقهما بعد ذلك بمثال ShipDebris.

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

إن ModuleManager عبارة عن حاوية تحافظ على وحدات السفينة في كل قائمة (مما يتيح سهولة التكرار) وخريطة تجزئة (تسمح بالوصول السهل عبر الإحداثيات المحلية).

من الواضح أن فئة ShipModule تمثل وحدة سفينة. إنها فئة تجريدية تحدد بعض وسائل الراحة والسمات التي تمتلكها كل وحدة. تكون كل فئة فرعية تابعة للمجموعة مسؤولة عن إنشاء كائن وشكل العرض الخاصين بها ، وتحديث نفسها إذا لزم الأمر. يتم تحديث الوحدات النمطية أيضًا عند إرفاقها بـ ShipDebris ، ولكن في هذه الحالة يتم تعيين علامة attachToShip على false.

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


تبسيط المشكلة

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

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

لا يمكن أن يتم تشغيل الدفعات أو إيقافها فقط ، ولا يمكن أن يتغير اتجاهها.

الآن بعد أن تخلينا عن الكمال والتعقيد ، أصبحت المشكلة أكثر بساطة. نحتاج أن نقرر ، لكل ما هو دافع ، ما إذا كان يجب تشغيله أو إيقافه ، اعتمادًا على موقعه على السفينة ومدخلات اللاعب. يمكننا تعيين مفتاح مختلف لكل داسر ، لكننا سننتهي بـ QWOP بين النجمي ، لذا سنستخدم مفاتيح الأسهم للتحول والتحرك ، وسؤال Q و W للقذف.


حالة بسيطة: تحريك السفينة إلى الأمام وإلى الخلف

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

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

Gamedev Maths and Physics: Using Torque and Thrusters to Correctly Maneuver a Player-Designed Spaceship

تكوين سفينة لا يمكنه التحرك للخلف


تدوير السفينة

Gamedev Maths and Physics: Using Torque and Thrusters to Correctly Maneuver a Player-Designed Spaceship

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

تبين أن ما نبحث عنه هنا هو معادلة عزم الدوران - وتحديدًا إشارة وحجم عزم الدوران.

لذلك دعونا نلقي نظرة على ما هو عزم الدوران. يُعرَّف العزم على أنه مقياس لمقدار قوة التأثير على كائن ما يؤدي إلى تدوير الكائن:

Gamedev Maths and Physics: Using Torque and Thrusters to Correctly Maneuver a Player-Designed Spaceship

ونظرًا لأننا نريد تدوير السفينة حول مركز كتلتها ، فإن [Latex] r [/ latex] هو ناقل المسافة من موضع نظام الدفع لدينا إلى مركز كتلة السفينة بأكملها. يمكن أن يكون مركز الدوران أي نقطة ، ولكن مركز الكتلة هو على الأرجح ما يتوقعه اللاعب.

متجه القوة [لاتكس] F [/ latex] عبارة عن متجه اتجاه وحدة يصف اتجاه جهاز الرفع لدينا. في هذه الحالة ، نحن لا نهتم بالعزم الفعلي ، فقط بعلامته ، لذا لا بأس من استخدام متجه الاتجاه فقط.

نظرًا لأن المنتج المتقاطع لا يتم تعريفه لمتجهين ثنائي الأبعاد ، فسوف نعمل ببساطة مع متجهات ثلاثية الأبعاد ونعين المكون [latex] z [/ latex] على 0 ، مما يجعل الرياضيات مبسطة بشكل جميل:

[latex]
\tau = r \times F \\
\tau = (r_x,\quad r_y,\quad 0) \times (F_x,\quad F_y,\quad 0) \\
\\ tau = (-0 \\ cdot F_y + r_y \\ cdot 0، \\ quad 0 \\ cdot F_x - r_x \\ cdot 0، \\ quad -r_y \\ cdot F_x + r_x \\ cdot F_y) \\\\
\tau = (0,\quad 0,\quad -r_y \cdot F_x + r_x \cdot F_y) \\
\tau_z = r_x \cdot F_y - r_y \cdot F_x \\
[/latex]

Gamedev Maths and Physics: Using Torque and Thrusters to Correctly Maneuver a Player-Designed Spaceship

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

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


استنتاج

الحل الموضح سهل التطبيق ويعمل بشكل جيد في لعبة من هذا النوع. بالطبع ، هناك مجال للتحسين: هذا البرنامج التعليمي والتوضيحي لا يأخذ في الاعتبار أن السفينة قد تجرّب بواسطة شيء آخر غير لاعب بشري ، وتنفيذ طيار الذكاء الاصطناعي الذي يمكن أن يطير فعلا سفينة نصف مدمرة سيكون تحدي مثير جدا (واحد سآخذ لمواجهة في وقت ما ، على أي حال).

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.