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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

هنا لم يكن من الممكن إرفاق جميع الخلايا - تمت إزالة الخلايا الإضافية.
يتم تحويل النتيجة إلى صناديق متعددة:

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

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

بناء الروابط

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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