قبل بضعة أسابيع ، قررت العمل في لعبة لـ Game Boy ، والتي منحتني إبداعها سرورًا كبيرًا. اسم العمل هو أكوا والرماد. اللعبة مفتوحة المصدر ويتم نشرها على
جيثب .
كيف هذه الفكرة تتبادر إلى ذهني
حصلت مؤخرًا على وظيفة تدريب داخلي لإنشاء خلفية في PHP و Python لموقع جامعتي. هذا عمل جيد ومثير للاهتمام ، وأنا ممتن له للغاية. لكن ... في الوقت نفسه ، فإن كل هذا الكود الرفيع المستوى لتطوير الويب قد أصابني برغبة شديدة. وكانت الرغبة في العمل على مستوى منخفض مع البتات.
تلقيت ملخصًا أسبوعيًا عن itch.io حول اختناقات الألعاب في البريد ، والتي أعلنت بداية
Mini Jam 4 . لقد كان مربى لمدة 48 ساعة (جيدًا ، في الواقع أكبر قليلاً) ، حيث كان القيد هو إنشاء رسومات بأسلوب Game Boy. كان رد فعلي المنطقي الأول هو إنشاء لعبة البيرة لـ Game Boy. كان موضوع المربى "المواسم" و "اللهب".
بعد التفكير قليلاً في المؤامرة والميكانيكا التي يمكن تنفيذها في غضون 48 ساعة وتوافقها مع قيود الموضوع ، توصلت إلى
استنساخ للتفسير الجديد للمستوى من لعبة SNES لعام 1993 ، لعبة Tiny Toon Adventures: Buster Busts Loose! ، حيث يلعب اللاعب في دور Baster كرة القدم الأمريكية! .
لطالما أحببت كيف ابتكر المبدعون في هذا المستوى رياضة معقدة بشكل لا يصدق ، وتخلصوا من جميع الحيل والمواقف والعناصر الاستراتيجية ، كنتيجة للحصول على لعبة ممتعة ومثيرة للاهتمام للغاية. من الواضح أن مثل هذه النظرة المبسطة لكرة القدم الأمريكية لن تحل محل Madden ، تمامًا مثل NBA Jam (فكرة مشابهة: 4 لاعبين فقط في مجال أصغر بكثير مع طريقة لعب أكثر وضوحًا من اللعبة العادية) لن تحل محل سلسلة 2K. لكن هذه الفكرة لها سحر معين ، وتؤكد أرقام مبيعات NBA Jam هذا.
كيف يرتبط كل هذا بفكرتي؟ قررت أن تأخذ مستوى كرة القدم هذا وأن أعيد صياغته بحيث يظل مشابهاً للمستوى الأصلي وفي نفس الوقت جديد. أولاً ، لقد خفضت اللعبة إلى أربعة لاعبين فقط - مدافع واحد ومهاجم واحد. تم القيام بذلك بشكل أساسي بسبب القيود المفروضة على الأجهزة ، ولكن في نفس الوقت سيسمح لي بتجربة قليلاً مع AI أكثر ذكاءً ، وليس مقصوراً على مبدأ "الجري يسارًا والقفز في بعض الأحيان" من اللعب على SNES.
من أجل التوافق مع الموضوع ، سأستبدل البوابات بأعمدة محترقة ، أو بألعاب نيران ، أو بشيء من هذا القبيل (لم أقرر بعد) ، وكرة كرة القدم بها مشاعل ودلاء من الماء. سيكون الفائز هو الفريق الذي يتحكم في كل من النيران ، وحول هذا المفهوم البسيط يمكنك بسهولة التوصل إلى مؤامرة. يتم أخذ الفصول في الاعتبار أيضًا: قررت أن الفصول ستتغير كل منعطف ، بحيث يحصل فريق الإطفاء على ميزة في الصيف وفريق الإطفاء في فصل الشتاء. هذه الميزة تشبه العقبات في الحقل التي تتداخل فقط مع الفريق المنافس.
بالطبع ، عند إنشاء فريقين ، كانت هناك حاجة لحيوانين لهذا الحب ولا يحبان النار. في البداية كنت أفكر في النمل الناري وبعض حشرات الماء ، والصلاة وما شابه ذلك ، ولكن بعد دراسة هذه المشكلة ، لم أجد أي حشرات نشطة في فصل الشتاء ، لذلك استبدلتهم بالثعالب القطبية والرخويات. الثعالب القطبية مثل الثلج ، والرغبات الرقيقة تحب الاستلقاء في الشمس ، لذلك يبدو أن كل شيء منطقي. في النهاية ، إنها مجرد لعبة لـ Game Boy.
بالإضافة إلى ذلك ، في حالة استمرار هذا الأمر ، فإن اللعبة لم تكن على وشك الانتهاء. على أي حال ، كان متعة على أي حال.
لعبة فتى التدريب
تحتاج أولا إلى تحديد المتطلبات. قررت أن أكتب لـ DMG (الاسم الداخلي لنموذج Game Boy ، وهو اختصار لـ Dot Matrix Game). أساسا من أجل تلبية متطلبات المربى اللعبة ، ولكن أيضا لأنني أردت حقا أن. شخصيا ، لم يكن لدي مطلقًا ألعاب لـ DMG (على الرغم من وجود العديد من الألعاب لـ Game Boy Color) ، لكنني أجد أن جماليات 2 بت هي قيود جميلة ومثيرة للاهتمام للتجارب. ربما سأضيف لونًا إضافيًا لـ SGB و CGB ، لكن حتى الآن لم أفكر في ذلك.
قررت أيضًا استخدام خرطوشة مع ذاكرة الوصول العشوائي (RAM) + 32 كيلو بايت بدون ذاكرة الوصول العشوائي ، فقط في حالة رغبتي في إنشاء نسخة مادية من اللعبة. CatSkull ، التي نشرت العديد من ألعاب Game Boy ، مثل Sheep it Up! ، لديها
خراطيش فلاش رخيصة الثمن للغاية تبلغ 32 كيلوبايت للبيع والتي تعد مثالية بالنسبة لي. هذا هو قيد إضافي آخر ، لكنني لا أعتقد أنه في المستقبل القريب يمكنني التغلب على وحدة التخزين 32K مع هذه اللعبة البسيطة. أصعب شيء سيكون مع الرسومات ، وإذا كان كل شيء سيئًا تمامًا ، فسأحاول ضغطه.
بالنسبة لعمل Game Boy ، فكل شيء معقد للغاية. ومع ذلك ، لكي أكون أمينًا ، من بين جميع لوحات التحكم الرجعي التي كان عليّ أن أعمل معها ، كان Game Boy أكثر متعة. لقد بدأت مع برنامج
تعليمي ممتاز (على الأقل لأول مرة ، لأنه لم يكتمل على الإطلاق) من قبل مؤلف AssemblyDigest. أدركت أنه من الأفضل أن تكتب بطريقة ASM ، مهما كانت مؤلمة في بعض الأحيان ، لأن الجهاز غير مصمم لـ C ، ولم أكن متأكدًا من أن لغة Wiz الرائعة المذكورة في البرنامج التعليمي ستكون مناسبة على المدى الطويل. بالإضافة إلى ذلك ، أفعل هذا بشكل رئيسي لأنه
يمكنني العمل مع ASM.
تحقق من الالتزام 8c0a4eaأول شيء فعله هو الحصول على Game Boy للإقلاع. إذا لم يتم العثور على شعار Nintendo عند إزاحة
$104
، ولم يتم تكوين باقي الرأس بشكل صحيح ، فسوف تفترض معدات Game Boy أن الخرطوشة قد تم إدخالها بشكل غير صحيح وسوف ترفض التحميل. حل هذه المشكلة بسيط للغاية ، لأنه قد تم بالفعل كتابة الكثير من البرامج التعليمية حول هذا الموضوع.
إليك كيفية حل مشكلة العنوان. لا يوجد شيء يستحق عناية خاصة.
سيكون من الصعب تنفيذ إجراءات ذات مغزى بعد التحميل. من السهل جدًا جعل النظام يدخل في دورة مشغول لا حصر له يعمل فيها سطرًا واحدًا من التعليمات البرمجية مرارًا وتكرارًا. يبدأ تنفيذ التعليمات البرمجية مع التسمية
main
(حيث يشير الانتقال إلى العنوان
$100
) ، لذلك تحتاج إلى إدراج بعض التعليمات البرمجية البسيطة هناك. على سبيل المثال:
main: .loop: halt jr .loop
ولا يفعل شيئًا على الإطلاق سوى الانتظار لبدء المقاطعة ، وبعد ذلك يعود إلى التسمية
.loop
. (فيما يلي ، سأحذف الوصف التفصيلي لـ ASM. إذا
شعرت بالارتباك ،
تحقق من وثائق المجمّع التي أستخدمها .) قد تكون فضوليًا لماذا لا أعود إلى الملصق
main
. هذا لأنني أريد أن يكون كل شيء قبل تسمية
.loop
هو تهيئة البرنامج وكل شيء بعد حدوثه في كل إطار. وبالتالي ، لست مضطرًا لتجاوز دورة تحميل البيانات من الخرطوشة ومسح الذاكرة في كل إطار.
لنأخذ خطوة أخرى. تحتوي حزمة المجمّع RGBDS التي أستخدمها على محول صور. نظرًا لأنني لم أرسم في هذه المرحلة أي موارد للعبة ، فقد قررت استخدام الزر أحادي اللون من صفحتي حول كصورة نقطية للاختبار. باستخدام RGBGFX ، قمت بتحويله إلى تنسيق Game Boy واستخدم الأمر .incbin collectler لإدخاله بعد الوظيفة
main
.
لعرضه على الشاشة ، أحتاج إلى ما يلي:
- شاشات الكريستال السائل قبالة
- تعيين لوحة
- تعيين موقف التمرير
- مسح ذاكرة الفيديو (VRAM)
- تحميل الرسومات البلاط في VRAM
- تحميل VRAM خريطة خلفية البلاط
- قم بتشغيل شاشة LCD مرة أخرى
شاشات الكريستال السائل قبالة
للمبتدئين ، وهذا يصبح أخطر عقبة. في لعبة Game Boy الأولى ، من المستحيل ببساطة كتابة البيانات على VRAM في أي وقت. من الضروري الانتظار للحظة التي لا يرسم فيها النظام أي شيء. تقليد توهج الفسفور في تليفزيونات CRT القديمة ، تسمى الفترة الفاصلة بين كل إطار عندما يكون VRAM مفتوحًا Vertical-Blank أو VBlank (في CRT يعد دافعًا لتفريغ حزمة kinescope أثناء الفحص العكسي). (يوجد أيضًا HBlank بين كل سطر من الشاشة ، ولكنه قصير جدًا.) ومع ذلك ، يمكننا التغلب على هذه المشكلة عن طريق إيقاف تشغيل شاشة LCD ، أي أنه يمكننا التسجيل في VRAM بغض النظر عن مكان وجود مسار الفسفور في شاشة CRT.
إذا كنت مرتبكًا ، فيجب
أن تشرح لك هذه المراجعة كثيرًا . في ذلك ، يتم النظر في السؤال من وجهة نظر SNES ، لذلك لا تنسى أنه لا يوجد شعاع إلكتروني ، والأرقام مختلفة ، ولكن في كل شيء آخر يكون قابلاً للتطبيق تمامًا. في الأساس ، نحتاج إلى تعيين علم FBlank.
ومع ذلك ، فإن حيلة Game Boy هي أنه يمكنك فقط إيقاف تشغيل شاشة LCD أثناء VBlank. وهذا هو ، علينا أن ننتظر VBlank. للقيام بذلك ، استخدم المقاطعات. المقاطعات هي إشارات على أن Game Boy يرسل الأجهزة إلى وحدة المعالجة المركزية. إذا تم تعيين معالج المقاطعة ، يتوقف المعالج عن عمله ويستدعي المعالج. يدعم Game Boy خمسة مقاطعات ، ويبدأ أحدها عند بدء تشغيل VBlank.
يمكن التعامل مع المقاطعات بطريقتين مختلفتين. الأول والأكثر شيوعًا هو مهمة
معالج المقاطعة الذي يعمل كما شرحت أعلاه. ومع ذلك ، يمكننا تمكين مقاطعة معينة وتعطيل جميع معالجات من خلال تعيين علامة التمكين لهذا المقاطعة واستخدام شفرة التشغيل. عادة ما لا يفعل شيئًا ، لكن له تأثير جانبي للخروج من شفرة التشغيل HALT ، والتي توقف وحدة المعالجة المركزية قبل حدوث مقاطعة. (يحدث هذا أيضًا عند تشغيل المعالجات ، مما يسمح لنا بالخروج من دورة HALT بشكل
main
.) في حال كنت مهتمًا ، سنقوم أيضًا بإنشاء معالج VBlank بمرور الوقت ، لكن الكثير منه سيعتمد على قيم معينة في عناوين معينة. نظرًا لعدم تعيين أي شيء في ذاكرة الوصول العشوائي حتى الآن ، فقد تؤدي محاولة استدعاء معالج VBlank إلى تعطل النظام.
لتعيين القيم ، نحتاج إلى إرسال أوامر إلى سجلات أجهزة Game Boy. هناك عناوين ذاكرة خاصة ترتبط مباشرة بأجزاء مختلفة من الجهاز ، في حالتنا ، وحدة المعالجة المركزية ، والتي تتيح لك تغيير طريقة عملها. نحن مهتمون بشكل خاص بالعناوين
$FFFF
(حقل بت تمكين المقاطعة) ،
$FF0F
(حقل بت
$FF0F
المنشط ولكن غير
$FF0F
) و
$FF40
(تحكم LCD). يمكن العثور
على قائمة بهذه السجلات
على الصفحات المرتبطة بقسم "الوثائق" بقائمة Awesome Game Boy Development.
لإيقاف تشغيل شاشة LCD ، نقوم بتشغيل مقاطعة VBlank فقط ، حيث نخصص قيمة
$01
$FFFF
،
$FF0F == $01
HALT حتى يتم استيفاء الشرط
$FF0F == $01
، ثم
$FF40
بت 7 من العنوان
$FF40
إلى 0.
وضع لوحة والتمرير الموقف
هذا سهل القيام به. الآن بعد إيقاف تشغيل شاشة LCD ، لا داعي للقلق بشأن VBlank. لتعيين موضع التمرير ، يكفي تعيين سجلات X و Y على 0. مع اللوحة ، كل شيء أصعب قليلاً. في Game Boy ، يمكنك تعيين ظلال من الرسومات الأولى إلى الرابعة لأي من ظلال الرمادي الأربعة (أو الأخضر المستنقع ، إذا كنت تريد) ، وهو أمر مفيد لإجراء انتقالات وما شابه ذلك. قمت بتعيين تدرج بسيط على هيئة لوحة ، تم تعريفها على أنها قائمة من البتات
%11100100
.
مسح VRAM وتحميل رسومات البلاط
عند بدء التشغيل ، ستتألف كل البيانات الرسومية وخريطة الخلفية فقط من شعار Nintendo للتمرير ، والذي يتم عرضه عند بدء تشغيل النظام. إذا قمت بتشغيل العفاريت (يتم تعطيلها افتراضيًا) ، فسيتم توزيع القمامة عبر الشاشة. تحتاج إلى مسح ذاكرة الفيديو للبدء من نقطة الصفر.
للقيام بذلك ، أحتاج إلى وظيفة مثل
memset
من C. (أحتاج أيضًا إلى
memcpy
تمثيلي لنسخ بيانات الرسومات.) تقوم وظيفة
memset
بتعيين جزء الذاكرة المحدد إلى بايت معين. سيكون من السهل بالنسبة لي تنفيذ هذا بنفسي ، لكن
البرنامج التعليمي AssemblyDigest لديه بالفعل هذه الوظائف ، لذلك يمكنني استخدامها.
في هذه المرحلة ، يمكنني مسح VRAM باستخدام
memset
عن طريق كتابة
$00
(على الرغم من أن الالتزام الأول استخدم القيمة
$FF
، والتي عملت أيضًا) ، ثم قم بتحميل رسومات التجانب في VRAM باستخدام
memcpy
. بشكل أكثر تحديدًا ، أحتاج إلى نسخه إلى العنوان
$9000
، لأن هذه الإطارات تستخدم فقط لرسومات الخلفية. (يتم استخدام العناوين
$8000-$87FF
فقط لبلاط sprite ، والعناوين
$8800-$8FFF
شائعة في كلا النوعين.)
إعداد خريطة البلاط
لدى Game Boy طبقة خلفية واحدة ، مقسمة إلى بلاط 8x8. تأخذ طبقة الخلفية نفسها حوالي 32 × 32 من البلاط ، أي أن حجمها الإجمالي 256 × 256. (للمقارنة: تتميز شاشة وحدة التحكم بدقة 160 × 144). كنت بحاجة إلى الإشارة يدويًا إلى البلاط الذي يتكون من خط الصورة الخاص بي. لحسن الحظ ، تم ترتيب جميع التجانبات بالترتيب ، لذلك كنت بحاجة فقط لملء كل سطر بالقيم من
N*11
إلى
N*11 + 10
، حيث
N
هو رقم السطر ، بينما تملأ عناصر التجانب المتبقية 22
$FF
.
تشغيل شاشات الكريستال السائل
هنا لسنا بحاجة إلى الانتظار للحصول على VBlank ، لأن الشاشة لا تزال لن تعمل حتى VBlank ، لذلك كتبت للتو إلى سجل التحكم LCD مرة أخرى. لقد قمت أيضًا بتضمين طبقات الخلفية والعفريت ، وأشرت أيضًا إلى العناوين الصحيحة لخريطة التجانب ورسومات التجانب. بعد ذلك حصلت على النتائج التالية. لقد قمت أيضًا بتشغيل معالجات المقاطعة مرة أخرى باستخدام شفرة التشغيل
ei
.
في هذه المرحلة ، لجعلها أكثر إثارة للاهتمام ، كتبت معالج مقاطعة بسيط للغاية لـ VBlank. بإضافة شفرة التشغيل الانتقالية عند
$40
، يمكنني جعل المعالج أي وظيفة أحتاج إليها. في هذه الحالة ، كتبت وظيفة بسيطة تقوم بتمرير الشاشة لأعلى ولأسفل.
وهنا النتائج النهائية. [إضافة: لقد أدركت للتو أن GIF لم يتم حلها بشكل صحيح ، يجب أن تنقل الصورة باستمرار.]
حتى الآن ، لا شيء يثير الدهشة بشكل خاص ، لكن ما زال رائعًا أنه من الناحية النظرية يمكنني الحصول على لعبة Game Boy Color القديمة الخاصة بي ومعرفة كيفية تنفيذ التعليمات البرمجية الخاصة بي.
المرح مع أوراق متقلب
لرسم شيء ما على الشاشة ، أحتاج بطبيعة الحال إلى نوع من العفريت. بعد دراسة وحدة معالجة الصور (PPU) بوحدة تحكم Game Boy ، قررت التركيز على 8x8 أو 8x16 sprites. من المحتمل ، سأحتاج إلى الخيار الأخير ، ولكن فقط لكي أشعر بالحجم ، قمت بسرعة بتدوين لقطة شاشة للعبة بمقياس 1: 8 على ورق متقلب.
أردت أن أترك الجزء العلوي من الشاشة تحت هود. يبدو لي أن الأمر سيبدو أكثر طبيعية من الأسفل ، لأنه عندما ينتهي الأمر ، إذا كانت الشخصيات تحتاج إلى حظر HUD مؤقتًا ، كما في Super Mario Bros ، فيمكنهم القيام بذلك. لن تحتوي هذه اللعبة على أي نظام أساسي معقد ، وفي الواقع تصميم المستوى أيضًا ، لذلك لا أحتاج إلى عرض نظرة عامة جدًا على هذا المجال. سيكون موقع الأحرف على الشاشة ، وربما العوائق التي تظهر من وقت لآخر ، كافية. لذلك ، لا أستطيع تحمل العفاريت كبيرة جدا.
لذلك ، إذا كان مربع واحد عبارة عن بلاط 8 × 8 ، فلن يكون العفريت الواحد كافيًا ، بغض النظر عن الحجم الذي أختاره. هذا صحيح بشكل خاص نظرًا لأنه لن تكون هناك حركة رأسية تقريبًا في اللعبة ، باستثناء القفزات. لذلك قررت إنشاء العفاريت من أربعة العفاريت 8x16. كان الاستثناء هو ذيل الثعلب الذي يحتل اثنين من العفاريت 8x16. بعد عمليات حسابية بسيطة ، أصبح من الواضح أن ثعالبين واثنين من حزم رحمه الله سيحتلان 20 من 40 عدوانية ، أي أنه سيكون من الممكن إضافة العديد من العفاريت الإضافية. (8x8 sprites ستنفد بسرعة من الحد الأقصى ، وهو ما لا أريد القيام به في المراحل المبكرة من التطوير.)
الآن ، أنا فقط بحاجة لرسم العفاريت. فيما يلي رسومات تقريبية على ورق متقلب. لدي شبح انتظار ، وشبح "تفكير" لاختيار ما إذا كنت تريد المرور أو الجري ، كما هو الحال في لعبة SNES ... وهذا كل شيء. لقد خططت أيضًا لتكوين نقوش من الشخصيات الجري والقفز على الشخصيات والشخصيات التي ينتزعها المعارضون. ولكن بالنسبة للمبتدئين ، وجهت فقط العفاريت في الانتظار والتفكير ، حتى لا تعقد. ما زلت لم أفعل الباقي ، ولست بحاجة للقيام بذلك.
نعم ، أنا أعلم ، أنا لا أرسم جيدًا. المنظور شيء صعب. (نعم ، هذا الوجه من الثعلب القطبي أمر فظيع.) لكنه يناسبني تمامًا. لا يحتوي تصميم الشخصيات على أي ميزات خاصة ، ولكنه مناسب لمربى اللعبة. بالطبع ، لقد استخدمت ابن حزم رحمه الله الحقيقي والثعالب القطبية كمراجع. هل هو غير محسوس؟
لا يمكنك قول ذلك. (للسجل: بعد أن نظرت للتو إلى هذه الصور مرة أخرى ، أدركت أن هناك فرقًا كبيرًا بين أحجار أبو بريص والسحالي. لا أعرف ماذا أفعل بهذا ، باستثناء اعتبار نفسي غبيًا ...) أعتقد أنه يمكنك تخمين أن مصدر الإلهام لـ خدم Blaze the Cat من سلسلة ألعاب Sonic كرئيس للثعلب.
في البداية ، أردت أن يكون المدافعون والمهاجمون في كل فريق من الجنسين ، وكان من السهل التمييز بينهم. (كنت سأسمح للاعبين أيضًا باختيار جنس شخصيتهم). ومع ذلك ، فإن هذا سيتطلب المزيد من الرسم. لذلك أنا استقر على ابن حزم رحمه الله الذكور والثعالب الإناث.
وأخيراً ، قمت برسم شاشة البداية لأن هناك مكانًا لها على قطعة من الورق المربّع.
نعم ، لا تزال الإجراءات التي تطرحها بعيدة عن المثالية. يجب أن يكون الثعلب القطبي أكثر انزعاجًا وجريًا ، وينبغي أن يكون أبو بريص مهددًا. Defender Fox في الخلفية - مرجعًا ممتعًا للفن في مربع Doom.
رقمنة العفاريت
ثم بدأت في تحويل الرسومات الورقية إلى نقوش. لهذا السبب ، استخدمت برنامج GraphicsGale ، والذي أصبح مؤخرًا مجانًا. (أعلم أنه يمكنك استخدام asesprite ، لكنني أفضل GraphicsGale.) تبين أن العمل على العفاريت أصبح أكثر تعقيدًا مما توقعت. كل من هذه المربعات من العفاريت الموضحة أعلاه تأخذ ما يصل إلى 4 بكسل في شبكة 2x2. وغالبًا ما تحتوي هذه المربعات على تفاصيل أكثر من 4 بكسل. لذلك ، كان علي أن أتخلص من العديد من تفاصيل الرسومات. في بعض الأحيان كان من الصعب الالتزام بشكل بسيط ، لأنه كان من الضروري ترك مكان مقبول للعينين أو الأنف. لكن يبدو لي أن كل شيء يبدو جيدًا ، حتى لو أصبح العفريت مختلفًا تمامًا.
فقدت عيون الثعلب شكلها اللوز وتحولت إلى خط ارتفاع اثنين بكسل. احتفظت عيون زغة استدارتها. كان لابد من توسيع رأس أبو بريص ، والتخلص من الأكتاف العريضة ، وكل الانحناءات التي كان يمكن للثعلب أن يملسها بشكل كبير. لكن بصراحة ، كل هذه التغييرات السهلة ليست سيئة للغاية. في بعض الأحيان بالكاد يمكنني اختيار أي من الاختلافات أفضل.
GraphicsGale لديها أيضا وظائف مريحة للطبقات والرسوم المتحركة. هذا يعني أنه يمكنني تحريك ذيل الثعلب بشكل منفصل عن جسدها. يساعد هذا كثيرًا في توفير مساحة VRAM الثمينة لأنني لست بحاجة إلى تكرار الذيل في كل إطار. بالإضافة إلى ذلك ، هذا يعني أنه يمكنك أن ترتدي ذيلك بسرعة متغيرة ، وتبطئ عندما تقف الشخصية ، وتسريع أثناء الركض. ومع ذلك ، هذا يجعل البرمجة أكثر تعقيدًا قليلاً. ولكن ما زلت سأقوم بهذه المهمة. لقد استقرت على 4 إطارات من الرسوم المتحركة ، لأن هذا يكفي.
قد تلاحظ أن الثعلب القطبي يستخدم ثلاثة أفتح ظلال من اللون الرمادي ، بينما يستخدم أبو بريص الظلال الثلاثة الأغمق من اللون الرمادي. في GameBoy ، هذا مقبول ، لأنه على الرغم من أنه لا يمكن أن يكون هناك سوى ثلاثة ألوان في العفريت ، فإن وحدة التحكم تسمح لك بتحديد لوحين. لقد قمت بذلك حتى يتم استخدام لوح الألوان 0 للثعالب ، بينما يتم استخدام لوحة الألوان 1 لأدوات الرهان geckos ، كل هذه المجموعة من اللوحات المتاحة قد انتهت ، لكنني لا أعتقد أنني بحاجة إلى الآخرين.
أنا أيضا بحاجة لرعاية الخلفية. لم أكن أزعج رسوماته ، لأنني خططت أن يكون لونًا صلبًا أو نمطًا هندسيًا بسيطًا. لم أقم بعد رقمي شاشة التوقف ، لأنني لم يكن لدي ما يكفي من الوقت.
تحميل العفاريت في اللعبة
تحقق مع الالتزام
be99d97 .
بعد حفظ كل إطار فردي لرسومات الحروف ، كان من الممكن البدء في تحويلها إلى تنسيق GameBoy. اتضح أنه في RGBDS هناك أداة مريحة للغاية لهذا يسمى RGBGFX. يمكنك تسميته باستخدام الأمر
rgbgfx -h -o output.bin input.png
وسيخلق مجموعة من البلاط المتوافق مع GameBoy. (يحدد رمز التبديل -h وضع التجانب المتوافق مع 8x16 بحيث يتم إجراء التحويل من أعلى إلى أسفل ، وليس من اليسار إلى اليمين.) ومع ذلك ، لا يوفر ارتباطات ولا يمكنه تتبع التجانبات المكررة عندما يكون كل إطار صورة منفصلة. لكننا سنترك هذه المشكلة في وقت لاحق.
بعد إنشاء ملفات .bin الإخراج ، ببساطة إضافتها في المجمع باستخدام
incbin "output.bin"
. للحفاظ على كل شيء معًا ، قمت بإنشاء ملف مشترك "gfxinclude.z80" ، والذي يحتوي على جميع الرسومات المراد إضافتها.
ومع ذلك ، كان من الممل جدًا تجديد الرسومات يدويًا في كل مرة يتغير فيها شيء. لذا قمت بتحرير ملف build.bat ، مضيفًا السطر
for %%f in (gfx/*.png) do rgbds\rgbgfx -h -o gfx/bin/%%f.bin gfx/%%f
، والذي يحول كل ملف. بابوا نيو غينيا في المجلد / مجلد gfx إلى ملف bin وحفظه على gfx / bin. تبسيط كبير حياتي.
لإنشاء رسومات خلفية ، استخدمت طريقة أكثر كسولًا. RGBASM لديه توجيه
dw `
. يتبعه سطر من 8 قيم من 0 إلى 4 يساوي سطر واحد من بيانات البكسل. نظرًا لأن العفاريت في الخلفية كانت بسيطة جدًا ، فقد أصبح من الأسهل نسخ ولصق نمط هندسي بسيط لإنشاء نمط صلب أو مخطط أو رقعة الشطرنج. هنا ، على سبيل المثال ، يبدو وكأنه بلاط الأرض.
bg_dirt: dw `00110011 dw `00000000 dw `01100110 dw `00000000 dw `11001100 dw `00000000 dw `10011001 dw `00000000
انه يخلق سلسلة من المشارب تحول مع وهم المنظور. هذا هو نهج بسيط ولكنه ذكي. مع العشب كان أكثر تعقيدا قليلا. في البداية ، كانت مجموعة من الخطوط الأفقية 2 بكسل عالية ، لكنني أضفت يدويًا بعض البكسلات التي تضيف القليل من الضوضاء التي تجعل العشب يبدو أفضل:
bg_grass: dw `12121112 dw `12121212 dw `22112211 dw `11121212 dw `22112211 dw `21212121 dw `12121212 dw `12211222
تقديم الرسومات
في GameBoy ، يتم تخزين العفاريت في منطقة تسمى OAM ، أو ذاكرة سمة الكائن. يحتوي على سمات فقط (الاتجاه واللوحة والأولوية) ، بالإضافة إلى رقم التجانب. , .
. -, VRAM. GameBoy , , VRAM. , VRAM
memcpy
. , 6 4 VRAM. (VRAM , 128 .)
, OAM VBlank. , VBlank, , VBlank . ,
VBlank OAM VBlank.
, GameBoy , DMA (Direct Memory Access, ), . HiRAM ( DMA ), OAM ,
memcpy
. إذا كانت مهتمة ، يمكن العثور على التفاصيل المثيرة هنا .في هذه المرحلة ، يمكنني فقط إنشاء إجراء يحدد ما سيتم كتابته في النهاية إلى DMA. للقيام بذلك ، كنت بحاجة لتخزين حالة الكائنات في مكان آخر. كحد أدنى ، كان ما يلي مطلوبًا:- النوع (أبو بريص ، الثعلب القطبي ، أو قم بحمل أحد الفرق)
- الاتجاه
- موقف X
- موقف Y
- إطار الرسوم المتحركة
- توقيت الرسوم المتحركة
, , , . , , X, 16, , .
, VRAM . — , , — , . , .
.
and
%11
. VRAM 4 * ( 4 ), 4 , VRAM. ( ),
, .
, ,
,
and
وكانت درجة اثنين اختيرت بواسطتي هي 0 ، تم إجراء زيادة في مؤقت الكائن. وبالتالي ، يمكن لكل كائن فردي العد التنازلي توقيت الحركة في أي سرعة يحتاجها. لقد نجح ذلك تمامًا وسمح لي بإبطاء الذيل إلى مستوى معقول.الصعوبات
. , , , , . , , , .
. . , , .
, . , , , .
? .