إذا كنت مشتركًا في البرمجة ، فأنت على دراية بمفهوم الأخطاء. إذا لم يزعجونا ، فستصبح عملية التطوير أسرع وأكثر متعة. لكن هذه الأخطاء تنتظر لحظة لتدمير كودنا وجدول العمل والتدفق الإبداعي. لحسن الحظ ، هناك العديد من الأدوات والاستراتيجيات لقتل الأخطاء حتى في كود مبرمجي اللعبة القديمة.
أدوات التصحيح
واحدة من أفضل الطرق لتصحيح التعليمات البرمجية هي استخدام مصحح أخطاء. تحتوي بعض إصدارات محاكي FCEUX و Mesen على مصحح أخطاء مضمن يسمح لك بمقاطعة البرنامج في أي وقت للتحقق من صحة التعليمات البرمجية.
FCEUX المحاكي المصححتجدر الإشارة إلى أن هذه الطريقة مناسبة أكثر للمبرمجين المتقدمين الذين يعملون بلغة التجميع. لكننا جديدون ، لذلك سنكتب باللغة C (cc65). بالطبع ، سيتم تشغيل برنامج التحويل البرمجي وفقًا لقواعده الخاصة ، وسيكون من الصعب علينا التعامل مع رمز الجهاز الذي تم تجميعه من رمز C.
محرر عرافة FCEUX
دعنا نقول أننا بحاجة إلى ملاحظة نوع من المتغير أو مجموعة. أضف السطر التالي إلى خيارات linker (ld65):
-Ln labels.txt
بعد ترجمة المشروع ،
labels.txt
ملف
labels.txt
في المجلد الخاص به. فقط افتحه في أي برنامج لعرض النصوص وابحث عن اسم المتغير الذي نريد ملاحظته.
(
ملاحظة: إذا أعلنت متغيرًا ثابتًا ، فلن يتم تضمينه في هذه القائمة. لذلك ، بدلاً من static unsigned char playerX
استخدم unsigned char playerX
)
الآن نحن نعرف عنوان المتغير المطلوب ، ليس سيئًا. دعونا العثور عليه في المصحح. قم بتشغيل ألعاب ROM في محاكي FCEUX. في قائمة Debug ، حدد عنصر Hex Editor ، وفي النافذة التي تفتح ، اضغط على Ctrl + G وأدخل عنوان المتغير الخاص بنا:
اضغط على "موافق" ، وسوف ينتقل المؤشر إلى العنوان الذي يوجد به المتغير. دعونا نلقي نظرة على ذلك:
قد يكون ذلك مفيدًا للتحقق مما إذا كان المصفوفة ممتلئًا بشكل صحيح أو لتتبع التغييرات في متغيرات معينة. بالإضافة إلى ذلك ، يمكنك أن تشعر أنك Big Brother ، تشاهد التعليمات البرمجية بعناية.
تحقق من أدوات قائمة تصحيح الأخطاء الأخرى المقلدة FCEUX مثل PPU Viewer ، عارض جدول الاسم ، إلخ.
تبسيط عملية التصحيح
وإذا كنا لا نريد تشغيل مصحح أخطاء في كل مرة لمراقبة متغير؟ هناك طريقة أكثر تقدماً وهي كتابة إجراء يعرض القيمة على الشاشة. لنجرب استخدام النتيجة في الواجهة لعرض موضع اللاعب على المحور ص:
إنه يعمل بشكل مثالي!
لقد أنشأ دوغ فراكر ،
صاحب مدونة الرجعية ومالك مدونة نسوج ، طريقة مماثلة لاستخدام المرئيات على الشاشة لأغراض تصحيح الأخطاء. ينشئ الإجراء الموضح أدناه خطًا رماديًا على الشاشة يوضح بوضوح درجة تحميل وحدة المعالجة المركزية:
يمكنك ببساطة نسخ هذا الإجراء في التعليمات البرمجية الخاصة بك أو تضمين مكتبة nesdoug.h في المشروع. يجب استدعاء الإجراء بعد الانتهاء من دورة اللعبة ، ثم سيتم عرض شريط رمادي على الشاشة.
لقد نجحت ، لكن يبدو أن لدي مشكلة أخرى! سنتخلص منه لاحقًا. في غضون ذلك ، دعنا ننتقل.
قوة وحدات الماكرو
يمكن أن تكون وحدات الماكرو أيضًا أداة تصحيح مفيدة. سوف يسمحون لك بالعثور على مكان في الكود الذي أصبح مصدر الخطأ.
دعنا ننشئ نوعًا من الماكرو يمنحنا إشارات في الوقت المناسب ، على سبيل المثال ، تشغيل صوت أو تحديد لوحة صفرية بالقيمة اللازمة. لدينا العديد من وحدات الماكرو التي تغير لوحة الصفر إلى ألوان الأحمر والأزرق والعشوائية ، وكذلك إنتاج الصوت:
كيف يعمل؟ لنفترض أنك نجحت في ترجمة مشروع ما ، وأنك بدأت تشغيل المحاكي باللعبة ، ثم انقر فوق الزر "ابدأ" و ...
يبدو أنه لا يوجد سوى شاشة بيضاء. بالإضافة إلى ذلك ، قد تقوم بعض المحاكيات بالإبلاغ عن "ازدحام وحدة المعالجة المركزية!" في شريط الحالة. ماذا تفعل بعد ذلك؟
أولاً ، تحتاج إلى ترجمة الشفرة التي يحدث فيها الخطأ. وهنا يأتي صوتي الكلي.
نحن نعرف بالتأكيد أن القائمة الرئيسية تعمل. دعونا نرى ما يحدث بعد ذلك:
playMainMenu(); player.lives = 9; points = 0; gameFlags = 0; while(current_level<7 && player.lives>0) { set_world(current_world); debugSound; playCurrentLevel(); }
لدي شكوك في تعطل اللعبة عند
set_world
إجراء
set_world
. دعونا التحقق من هذا الحدس. أنا ببساطة أدخل اسم الماكرو في السطر التالي بعد الإجراء الجاري التحقق منه.
نبدأ المشروع و ... أسمع صوتًا! أي أن هذا الإجراء كان ناجحًا ، ونحن بحاجة إلى التحقق مما يلي:
playCurrentLevel
. دعنا ننقل ماكرو التصحيح أدناه:
while(current_level<7 && player.lives>0) { set_world(); playCurrentLevel(): debugSound; }
أبدأ المشروع مرة أخرى ، لكن لا يمكنني سماع صوت. هذا يعني أن الإجراء لم يكتمل ، ويحدث فشل فيه.
في مثل هذه الحالات ، يجب عليك فتح رمز الإجراء ومتابعة تطبيق هذه التقنية حتى تتمكن من تضييق نطاق البحث عن موقع خلل محتمل.
يمكن أن يكون ماكرو تغيير لوح الألوان مفيدًا أيضًا للتحقق من الظروف. على سبيل المثال ، يقوم الرمز الخاص بنا بإجراء اختبار معقد لعدة شروط:
if ( (getTile(objX, objY+16) || collide16() ) || (objsOX[i] && objY>objsOX[i])) { debugRed; objsSTATE[i]=THWOMP_SMASH; objY=objsY[i]-=4; objsFRM[i]=0; sfx_play(SFX_THWOMP_SLAM_DOWN,2); }
إذا قمنا بتغيير لون اللوحة هنا ، فسوف نرى ما إذا كانت الحالة مرضية:
يبدو أن هذا الدجاج بخير. ولكن إذا لم يعمل العلم ، فلا يتم استيفاء أحد الشروط. في هذه الحالة ، تحتاج إلى التحقق منها جميعًا بشكل منفصل ، وبعد ذلك ، ربما ستجد خطأ آخر.
الخيار النووي
اكتشفت مؤخرًا أن أحد الأشباح في لعبتي يظهر نوعًا من السلوك المشبوه. من وقت لآخر ، رفض مهاجمة اللاعب.
ألقِ نظرة على هذا الشبح الذي أصابه خطأ - إنه يهاجم فقط عندما تكون الشخصية قريبة من وسط الشاشة:
بغض النظر عن مدى صعوبة دراستي لرمز هذا الإجراء ، لم أتمكن من معرفة مكان إخفاء الخطأ ، لذلك قررت اتخاذ تدابير متطرفة واختبار عمل هذا الرمز في بيئة تطوير حديثة.
أخذت كل ما أحتاجه: خريطة شاشة ، مصفوفة بسمات ملف التعريف ، رمز الإجراء ، وأدرجتها ببساطة في Visual Studio 2017:
على جهاز الكمبيوتر ، رمز يعمل بالضبط نفس الشيء. كما اتضح فيما بعد ، كان الخطأ مختبئًا في الإجراء الذي ملأ ذاكرة التخزين المؤقت لإيجاد عقبات بين اللاعب والعدو. تم ملء الصفيف بشكل غير صحيح. أنا متأكد من أنه يجب أن يكون هناك 0 بدلاً من 0x80.
لذا ، سأحاول تصحيح التعليمات البرمجية خطوة بخطوة لمعرفة سبب حدوث ذلك.
إنه أمر مضحك ، لكن يبدو أنني كنت أفعل الإجراءات في التسلسل الخاطئ. دعونا إصلاحه والتحقق من مجموعة مرة أخرى!
يبدو الآن أن المجموعة تملأ بشكل صحيح. وهذا هو ، أنا فقط بحاجة إلى إصلاح رمز cc65 وتجميع مشروع NES مرة أخرى.
لذلك ، يمكن أن تساعد أدوات التطوير الحديثة في تصحيح الخوارزميات وإصلاح الأخطاء.
تخلص من الحشرات بهدوء
البق مزعج ، كما يمكن رمز مزعج. مجرد التزام الهدوء ، لا تفقد السيطرة واستخدام مجموعة كاملة من الأدوات المتاحة للبحث عن هذه الآفات وتدميرها. جودة كودك وراحة البال ستزداد بشكل كبير.
هل ترغب في الحصول على نصائح مباشرة من متخصصي التصميم الرجعية؟ مرحبا بكم في الفتنة لدينا!
لعبتنا The Meating متاحة هنا !