توليد المستوى الإجرائي


انتهى العمل على البرمجة والرسومات والأصوات في بعض الألعاب الجديدة - تبقى فقط المستويات. عمل سهل وممتع ، ولكن لسبب ما يأتي بصعوبة كبيرة. ربما أثر التعب العام.


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


إنتباه! تحت قطع الكثير من النص وصور متحركة "الدهون".


تمهيدي


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


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


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



قررت أن أبدأ مع الأخيرين - يتم تنفيذهما للتو ، وإعطاء نتائج جيدة.


هيكل المولد


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


  1. إنشاء هندسة أولية (للاختيار من بينها - إما "BSP" أو تخطيط الغرفة).
  2. تطهير أقسام القمامة (مثل هذه الأقسام التي لا يمكن أن توجد في اللعبة).
  3. بناء الروابط.
  4. مسح الرسوم البيانية للقمامة (مثل مجموعات الأقسام المترابطة ، ولكن لا يوجد اتصال مع الأقسام المتبقية).
  5. مسح الاتصالات غير الضرورية (بناء شجرة امتداد ، يتم إعطاء ارتباط إلى الحد الأدنى من شجرة الامتداد ، لأن هناك صورة هناك ، ولكن بالنسبة للمولد ليس هناك حاجة للحد الأدنى).
  6. التوزيع العشوائي للاتصالات هو استعادة بعض الاتصالات البعيدة مرة أخرى (لنوع من المستوى "البشري") ، بالإضافة إلى تحويل البعض الآخر إلى مقاطع بين الأقسام (التي تدمج عدة أقسام في شكل واحد أكثر تعقيدًا).
  7. جيل الغرفة السرية.
  8. إنشاء "سيناريو" (أين سيكون القسمان الأولي والأخير ، والمسار الذي يجب تمريره من أجل الانتقال من الأول إلى النهائي).
  9. تحسين الاتصال.
  10. إنشاء أبواب ونوافذ.
  11. اختيار الإجراء الذي سيتم تنفيذه في هذا القسم (اضغط على المفتاح ، ارفع المفتاح أو ابحث عن الجدار السري).

لا يزال هناك ما يقرب من 12 نقطة ، لكنها لم تكتمل بعد (عندما أنهي ، سأكتب منشورًا منفصلاً عنها).


الجيل الهندسي الأولي: "BSP"



تم أخذ هذه الترجمة كأساس. لست متأكدًا من مقدار ما يحدث في هذه الخوارزمية بالقرب من BSP الحقيقي ، لذلك أكتب "BSP" بين علامتي اقتباس.


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



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



نفعل الشيء نفسه بشكل متكرر للمستطيلات الجديدة:



مرارا وتكرارا ، إلى حد ما:



ثم في كل مستطيل نختار "غرفة" - مستطيل من نفس الحجم الأصلي أو الأصغر (ولكن ليس أقل من 3x3 - المزيد على ذلك أدناه).



ثم يتم توصيل الغرف عن طريق الممرات. ولكن ليس كل واحد ، ولكن صعبًا قليلاً ، لأنه يتم تخزينه في هيكل يشبه "BSP" (انظر الخوارزمية الأصلية لمزيد من التفاصيل).



الممر الذي يربط المقاطع الأرجواني والأبيض.


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


بالإضافة إلى ذلك ، إذا عبرت الغرفة (الفيروز في الشكل) الممر ، فيجب أن تقسمه إلى قسمين مختلفين (وبالتالي ، يمكن رسم نفس الممر بألوان مختلفة):



وها هي النتيجة:



ثم تبدأ مرحلة وسم خلايا القمامة:



كما كتبت بالفعل ، لا يمكن لأي قطاع أن يكون أصغر من 3x3 خلية. ويرجع ذلك إلى حقيقة أن القطاع يجب أن يكون محاطًا بالجدران (خلية واحدة على الأقل على كل جانب) ، ويجب أن يحتوي على خلية مساحة حرة واحدة على الأقل:



لذلك ، يتم تسمية جميع الخلايا التي لا تتناسب مع هذه القاعدة. لكن خذها ولا يمكنك إزالتها - تختفي العديد من الاتصالات ، والمستوى ضئيل جدًا.


بدلاً من ذلك ، لكل خلية مصنفة ، يتم البحث عن القطاع الذي يمكنها الانضمام إليه (مراقبة قاعدة 3x3):



إذا كانت الخلية لا تزال لا يمكن أن تعزى إلى أي قطاع ، فسيتم حذفها (ولكن ليس في هذه الحالة - كل شيء على ما يرام هنا).


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



الجيل الهندسي الأولي: تخطيط الغرفة



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


أولاً ، تمتلئ ساحة اللعب بقيمة توقف معينة ، ثم يتم مسح منطقة مستطيلة بشكل عشوائي عليها:



يتم تنفيذ مرحلة تنظيف المستطيل العشوائي لعدد من المرات (العشوائية أيضًا) ، ونتيجة لذلك ، يتم الحصول على الخطوط الخارجية للمستوى:



في الفضاء الحر ، تتناثر نقاط نمو الغرفة بشكل عشوائي (الحد الأدنى لحجم الغرفة هو 3 × 3):



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



ثم يتم تحويل الغرف إلى صناديق متعددة:



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


والنتيجة مساحة مليئة بالكامل:



ثم يتم رسم polyboxes في شكل خطوط المسح ، و (كما في حالة مولد "BSP") ، تبدأ مرحلة وسم خلايا "القمامة":



وضمهم للقطاعات القائمة:



هنا لم يكن من الممكن إرفاق جميع الخلايا - تمت إزالة الخلايا الإضافية.


يتم تحويل النتيجة إلى صناديق متعددة:



تنظيف أقسام القمامة


في بعض الأحيان تنشأ أقسام لا يتم فيها احترام قاعدة 3x3:



يمكنك محاولة "استعادة" هذه الأقسام ، لكني ذهبت بطريقة أبسط ، وحذفها فقط:



بناء الروابط



لكل قسم ، يتم البحث عن جيرانه ، وفي أماكن الاتصال بهذه الأقسام ، يتم إنشاء اتصالات. يتم إنشاء الاتصالات على كلا الجانبين - إذا كان القسم A على اتصال بالقسم B ، فسيكون هناك اتصال من A إلى B ومن B إلى A. والنتيجة هي رسم بياني ثنائي الاتجاه.


تطهير المخططات الفرعية للقمامة


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



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


إزالة المركبات الزائدة


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



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


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


عشوائية الاتصال



فيما يلي ، سوف تأتي الرسوم التوضيحية من جيل آخر ، لأنه في الصورة السابقة كان هناك خطأ في المولد ، ونتيجة لذلك كانت الصور الأخرى غير صحيحة.


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


  1. تتم استعادة بعض الحواف المحذوفة.
  2. وبعضها يتحول إلى ممرات.

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



إذا بدا لك أنه في هذا الرسم التوضيحي ، عادت الاتصالات المحذوفة في الخطوة السابقة - فقد ظهر لك :). عندما قرأت النص ، بدا لي بهذه الطريقة أيضًا ، ولكن بعد النظر بعناية في الرسم التوضيحي السابق ، يصبح من الواضح أن كل شيء على ما يرام.


جيل الغرفة السرية


يتم تحديد القطاعات التي لها اتصال واحد فقط على الرسم البياني:



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



إنشاء البرنامج النصي



أولاً ، يتم تحديد القطاعات ذات الحد الأدنى من الاتصالات المجانية (أي تلك الأقرب إلى "حافة" الرسم البياني):



في هذا الرسم التوضيحي ، يتم تحديد قطاع واحد ، ولكن إذا كان هناك المزيد ، فسيتم تحديد قطاع على أي حال (عشوائيًا).


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


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



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


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


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



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


بعد ذلك ، يتم تحديد القطاع التالي ، ويتم تجميع القائمة ، ويتم تمييز هذه القائمة بسيناريو جديد:



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


يستمر هذا حتى لا يبقى هناك قطاعات حرة:



لم يتم تعيين نص برمجي لآخر قطاع ، ولكن تم فتح السيناريو فقط. سيكون هذا القطاع هو القطاع الذي يبدأ فيه اللاعب اللعبة.


لهذا المستوى:


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

تخطيطيًا ، يمكن إظهار ذلك على النحو التالي:



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


تحسين الاتصال



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


إنشاء أبواب ونوافذ



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


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

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


  1. في الخطوة الأولى ، يتم وضع الباب دائمًا ، لأنه ما فائدة الاتصال إذا كانت هناك نوافذ فقط.
  2. في الخطوة الثانية ، مع احتمال أعلى (75 ٪) ، يتم وضع نافذة من الباب.
  3. إذا كانت هناك خطوة ثالثة (على سبيل المثال ، الاتصال طويل) ، فيجب وضع نافذة عليه.
  4. في حالة الخطوة الرابعة ، يتم وضع الباب أو النافذة بشكل متساوٍ.
  5. إذا كان الاتصال طويلاً جدًا ، يعود المولد إلى الخطوة الثانية.

اختيار العمل


على الرغم من أن هذا لا يرتبط بالجيل ، إلا أن التصور يتغير في هذه الخطوة - الآن يتم رسم حدود القطاع بلون النص:



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


بعد ذلك ، حدد القطاعات التي يمكنك وضع المفاتيح فيها:



يتم اختيارهم ببساطة شديدة:


  • إذا كانت هذه غرفة سرية ، فلا يمكن أن يكون هناك "فتاحة" فيها ، ولا يمكن وضع المفتاح هناك.
  • لا يمكنك وضع المفتاح في القطاع النهائي أيضًا ، لأنه نهائي.
  • أيضًا ، لا يمكن للمفتاح فتح أبواب مزدوجة وثلاثية - نظرًا لميزات المحرك ، لا يمكن فتحها إلا باستخدام المفتاح (لا توجد مثل هذه القطاعات في الرسم التوضيحي أعلاه) .

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


في القطاعات المتبقية سيكون هناك مفاتيح.

Source: https://habr.com/ru/post/ar418685/


All Articles