نظام شخصيات الألعاب
جزء من قسم Object Oriented Programming في رحلة Dart على Coddy — الدرس 109 من 110.
التحدي
سهللنقم ببناء نظام شخصيات ألعاب يجمع كل مفاهيم البرمجة كائنية التوجه (OOP) التي أتقنتها! ستقوم بإنشاء فئات شخصيات مختلفة بقدرات وإحصائيات وآليات قتال فريدة - لمحاكاة كيفية عمل الشخصيات في لعبة حقيقية.
سيتم تنظيم نظامك عبر ستة ملفات:
character.dart: أنشئ فئة مجردة (abstract class) باسمCharacterتعمل كأساس لجميع أنواع الشخصيات. كل شخصية لديهاname(String)، و_healthخاص (int)، وattackPower(int)، وdefense(int). قم بتضمين getter للصحة وهذه الأساليب (methods):takeDamage(int damage)- يقلل الصحة بمقدارdamage - defense(الحد الأدنى للضرر الملحق هو 1، ولا يمكن أن تقل الصحة عن 0). يطبعname takes X damage! Health: Ybool isAlive()- يرجع true إذا كانت الصحة أكبر من 0- أسلوب مجرد
String attack()تقوم الفئات الفرعية بتنفيذه لأسلوب الهجوم الفريد الخاص بها
toString()لترجعname [Class] - HP: health, ATK: attackPower, DEF: defenseحيث تأتي Class منruntimeType.abilities.dart: أنشئ اثنين من الـ mixins اللذين يوفران قدرات خاصة:CanHeal- يوفر أسلوبheal(int amount). بما أن الـ mixins لا يمكنها الوصول مباشرة إلى الحقول الخاصة، يجب أن يحدد هذا الـ mixin أسلوباً مجرداًvoid restoreHealth(int amount)تقوم فئة الشخصية بتنفيذه. يستدعي أسلوبheal()الأسلوبrestoreHealth(amount)ويطبعname heals for amount HP!CanCastSpells- يوفرint mana(القيمة الافتراضية 100) وأسلوبcastSpell(String spellName, int manaCost)الذي يقلل المانا إذا كانت كافية، ويطبعname casts spellName!، ويرجع true. إذا كانت المانا غير كافية، يطبعNot enough mana!ويرجع false.
warrior.dart: أنشئ فئةWarriorترث منCharacter. المحاربون هم "tanks" ذوو دفاع عالٍ. قم بتهيئتها بـ 150 صحة، و 20 قوة هجوم، و 15 دفاع. قم بتنفيذattack()لترجعname swings a mighty sword!mage.dart: أنشئ فئةMageترث منCharacterوتستخدم mixins الـCanCastSpellsوCanHeal. السحرة ضعفاء جسدياً ولكنهم أقوياء. قم بتهيئتها بـ 80 صحة، و 35 قوة هجوم، و 5 دفاع. قم بتنفيذattack()لترجعname hurls a fireball!. قم بتنفيذrestoreHealth(int amount)لزيادة الصحة (بحد أقصى 80).archer.dart: أنشئ فئةArcherترث منCharacter. الرماة مقاتلون متوازنون. قم بتهيئتها بـ 100 صحة، و 25 قوة هجوم، و 10 دفاع. قم بتنفيذattack()لترجعname fires a precise arrow!main.dart: استعرض نظام الشخصيات الخاص بك عن طريق إنشاء واحد من كل نوع شخصية: محارب باسمThorin، وساحر باسمGandalf، ورامي سهام باسمLegolas. اطبع كل شخصية باستخدامtoString(). ثم قم بمحاكاة تسلسل معركة:- اطبع رسالة هجوم Thorin
- يتلقى Gandalf ضرراً قدره 30
- يلقي Gandalf تعويذة
Healing Light(تكلف 25 مانا) - يعالج Gandalf نفسه بمقدار 20 HP
- اطبع رسالة هجوم Gandalf
- يتلقى Thorin ضرراً قدره 40
- اطبع رسالة هجوم Legolas
- اطبع ما إذا كانت كل شخصية على قيد الحياة بالتنسيق:
name alive: true/false
المخرجات المتوقعة:
Thorin [Warrior] - HP: 150, ATK: 20, DEF: 15
Gandalf [Mage] - HP: 80, ATK: 35, DEF: 5
Legolas [Archer] - HP: 100, ATK: 25, DEF: 10
Thorin swings a mighty sword!
Gandalf takes 25 damage! Health: 55
Gandalf casts Healing Light!
Gandalf heals for 20 HP!
Gandalf hurls a fireball!
Thorin takes 25 damage! Health: 125
Legolas fires a precise arrow!
Thorin alive: true
Gandalf alive: true
Legolas alive: trueجرّب بنفسك
import 'warrior.dart';
import 'mage.dart';
import 'archer.dart';
void main() {
// TODO: أنشئ Warrior باسم "Thorin"
// TODO: أنشئ Mage باسم "Gandalf"
// TODO: أنشئ Archer باسم "Legolas"
// TODO: اطبع كل شخصية باستخدام toString()
// TODO: محاكاة تسلسل المعركة:
// 1. اطبع رسالة هجوم Thorin
// 2. يتلقى Gandalf ضرراً بمقدار 30
// 3. يلقي Gandalf تعويذة "Healing Light" (تكلف 25 mana)
// 4. Gandalf يعالج نفسه بمقدار 20 HP
// 5. اطبع رسالة هجوم Gandalf
// 6. يتلقى Thorin ضرراً بمقدار 40
// 7. اطبع رسالة هجوم Legolas
// 8. اطبع ما إذا كانت كل شخصية على قيد الحياة: "name alive: true/false"
}
جميع دروس Object Oriented Programming
1أساسيات الـ OOP
الملفات الخارجيةالمكتبات والـ Importsمقدمة في الـ OOPالـ Classes مقابل الـ Objectsالكلمة المفتاحية thisالـ Methodsمتغيرات الـ Instanceأساسيات الـ Constructorمراجعة - آلة حاسبة بسيطة4أمان الـ Null
مقدمة في أمان الـ NullNullable مقابل Non-Nullableعاملا الـ ? و !الكلمة المفتاحية Late وأمان الـ Nullالعوامل المدركة للـ Nullأمان الـ Null في الـ Classesمراجعة - نظام ملف تعريف المستخدم7الفئات المجردة والواجهات
الفئات المجردةالدوال المجردةالواجهات في Dartالواجهات الضمنيةالتنفيذ مقابل التوسيعالواجهات المتعددةمراجعة - حاسبة الأشكال10المجموعات والأنماط العامة
نظرة عامة على List و Set و Mapالمجموعات آمنة النوعالفئات العامةالدوال العامةقيود الأنماط العامةIterable و Iteratorملخص - التخزين العام13مفاهيم OOP المتقدمة
التركيب مقابل الوراثة (Composition vs Inheritance)دوال التوسعة (Extension Methods)الأصناف القابلة للاستدعاء (Callable Classes)الأصناف المختومة (Sealed Classes - Dart 3)السجلات (Records - Dart 3)الأنماط والمطابقة (Patterns & Matching - 3.0)التعدادات مع الدوال (Enums with Methods)2المنشئات في Dart
المنشئ الافتراضيالمنشئات المسماةقوائم التهيئةالمنشئات الثابتةالمنشئات المصنعيةالمنشئات الموجهةملخص - بناء الأشكال5التغليف (Encapsulation)
الأعضاء العامة مقابل الخاصةاتفاقية البادئة _الخصوصية على مستوى المكتبةتعمق في Getters و Settersإخفاء المعلوماتمراجعة - سجلات الطلاب8Mixins
مقدمة إلى Mixinsإنشاء Mixinsاستخدام Mixins متعددةالكلمة المفتاحية on في MixinsMixin مقابل الوراثة (Inheritance)Mixin مقابل الواجهة (Interface)مراجعة - نظام الحيوانات (Animal System)3خصائص الـ Class
أعضاء الـ Instance مقابل الـ Staticحقول Final و Constمتغيرات Lateالـ Static Methods والحقولدوال الـ Getters والـ Settersمراجعة - مدير الحساب البنكي6الوراثة
أساسيات الوراثةالكلمة المفتاحية superإعادة تعريف الدوال (Method Overriding)الوسم @overrideالكلمة المفتاحية final Classالدوال البانية والوراثةمراجعة - هيكلية الموظفين9تعدد الأشكال
أساسيات تعدد الأشكالتعدد الأشكال عبر الـ Interfacesالتحقق من النوع أثناء التشغيلالمعاملات is و asالكلمة المفتاحية Covariantملخص - معالج الدفع12البرمجة الكائنية غير المتزامنة (Async OOP)
Futures و async/awaitأساسيات الـ Streamsمتحكمات الـ Streamsالـ Constructors غير المتزامنةالعمليات غير المتزامنة في دوال الكلاسمراجعة - جالب البيانات (Data Fetcher)15أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبنمط المستودع