مكون شخصية اللعبة
جزء من قسم Object Oriented Programming في رحلة C# على Coddy — الدرس 69 من 70.
التحدي
سهللنقم ببناء نظام شخصيات ألعاب باستخدام نمط الهندسة القائم على المكونات (component-based architecture)! بدلاً من إنشاء تسلسلات هرمية جامدة للوراثة، ستقوم بتكوين الشخصيات عن طريق إرفاق مكونات مستقلة تتعامل مع سلوكيات محددة - وهو نهج مرن يستخدم على نطاق واسع في تطوير الألعاب.
ستقوم بتنظيم الكود الخاص بك عبر خمسة ملفات:
IComponent.cs: قم بتعريف واجهةIComponentفي مساحة الأسماءGame.Components. يجب أن يحتوي كل مكون على تابعUpdate()يطبع ما يفعله المكون.HealthComponent.cs: أنشئ فئةHealthComponentالتي تنفذIComponent. يجب أن تتبع نقاط الصحة الحالية والقصوى، مع توابع لـTakeDamage(int amount)وHeal(int amount). يجب ألا تقل الصحة أبداً عن 0 أو تزيد عن الحد الأقصى. قم بتضمينevent Action<int> HealthChangedالذي ينطلق كلما تغيرت الصحة، ممرراً قيمة الصحة الجديدة. يجب أن يطبع التابعUpdate()حالة الصحة الحالية.InventoryComponent.cs: أنشئ فئةInventoryComponentالتي تنفذIComponent. تدير هذه الفئة قائمة بأسماء العناصر مع توابعAddItem(string item)وRemoveItem(string item)(يعيدboolيشير إلى النجاح). يجب أن يطبع التابعUpdate()محتويات المخزن (inventory).Character.cs: أنشئ فئةCharacterفي مساحة الأسماءGameالتي تحمل مجموعة من المكونات. تحتاج شخصيتك إلى خاصيةNameوهذه التوابع:AddComponent(IComponent component)- يرفق مكوناً بالشخصيةGetComponent<T>()حيث T : IComponent - يعيد المكون الأول من النوع T، أو null إذا لم يتم العثور عليهUpdateAll()- يستدعيUpdate()لكل مكون مرفق
Program.cs: اجمع كل شيء معاً عن طريق إنشاء شخصية، وإرفاق المكونات، ومعالجة الأوامر.
ستتلقى المدخلات التالية:
- اسم الشخصية
- الصحة القصوى الأولية لـ HealthComponent
- عدد الأوامر المطلوب معالجتها
- لكل أمر: الإجراء متبوعاً بالبيانات ذات الصلة
تنسيقات الأوامر:
damage
{amount}
heal
{amount}
add_item
{itemName}
remove_item
{itemName}
updateتنسيقات المخرجات:
- عند تغير الصحة (عبر الحدث):
Health changed: {newHealth} - عند إضافة عنصر:
Added: {itemName} - عند إزالة عنصر:
Removed: {itemName}أوItem not found: {itemName} - تابع
Update()الخاص بـ HealthComponent:Health: {current}/{max} - تابع
Update()الخاص بـ InventoryComponent:Inventory: {item1}, {item2}, ...أوInventory: empty
على سبيل المثال، إذا كانت المدخلات هي:
Hero
100
7
add_item
Sword
add_item
Shield
damage
30
heal
10
remove_item
Potion
remove_item
Sword
updateيجب أن تكون المخرجات:
Added: Sword
Added: Shield
Health changed: 70
Health changed: 80
Item not found: Potion
Removed: Sword
Health: 80/100
Inventory: Shieldلاحظ كيف أن الشخصية لا ترث من أي شيء خاص - فهي ببساطة تحمل مكونات توفر السلوك. يستخدم التابع GetComponent<T>() الأنواع العامة (generics) للاسترجاع الآمن للأنواع، وتقوم الأحداث بالإخطار عند تغير الصحة. يتيح لك نهج التكوين (composition) هذا مزج المكونات ومطابقتها بحرية!
جرّب بنفسك
using System;
using Game;
using Game.Components;
class Program
{
public static void Main(string[] args)
{
// قراءة اسم الشخصية
string characterName = Console.ReadLine();
// قراءة الحد الأقصى الأولي للصحة
int maxHealth = Convert.ToInt32(Console.ReadLine());
// قراءة عدد الأوامر
int numCommands = Convert.ToInt32(Console.ReadLine());
// TODO: إنشاء Character بالاسم المعطى
// TODO: إنشاء HealthComponent مع maxHealth و InventoryComponent
// TODO: الاشتراك في حدث HealthChanged لطباعة: Health changed: {newHealth}
// TODO: إضافة كلا المكونين إلى الشخصية
// TODO: معالجة كل أمر
for (int i = 0; i < numCommands; i++)
{
string command = Console.ReadLine();
// TODO: التعامل مع كل نوع من الأوامر:
// - "damage": قراءة القيمة، واستدعاء TakeDamage في health component
// - "heal": قراءة القيمة، واستدعاء Heal في health component
// - "add_item": قراءة اسم العنصر، واستدعاء AddItem في inventory component
// - "remove_item": قراءة اسم العنصر، واستدعاء RemoveItem في inventory component
// - "update": استدعاء UpdateAll في character
}
}
}
جميع دروس Object Oriented Programming
1أساسيات OOP
الملفات الخارجيةNamespaces والتوجيهاتمقدمة في Classes و Objectsالكلمة المفتاحية 'this'Methods والمعاملاتFields مقابل PropertiesConstructorsObject Initializersمراجعة - آلة حاسبة بسيطة4الوراثة
صيغة الوراثة الأساسية (:)الكلمة المفتاحية 'base'الكلمات المفتاحية Virtual و Overrideالأصناف المختومة (Sealed Classes)الفئة الأساسية 'object'مراجعة - هيكلية الموظفين7ميزات متقدمة
تحميل العوامل (Operator Overloading)المفهرسات (Indexers (this[]))إعادة تعريف ()ToStringدوال التوسعة (Extension Methods)ملخص - Custom List2الخصائص والأعضاء الساكنة (Static Members)
الخصائص المطبقة تلقائيًا (Auto-Implemented Properties)خصائص القراءة فقط والكتابة فقطالحقول والدوال الساكنة (Static)الفئات الساكنة (Static Classes)الأعضاء ذات البنية التعبيرية (Expression-Bodied Members)5تعدد الأشكال والواجهات (Polymorphism & Interfaces)
تعدد الأشكال: وقت التجميع مقابل وقت التشغيلالواجهة مقابل الفئة المجردة (Abstract Class)الواجهات المتعددةالواجهات الصريحةUpcasting و Downcastingملخص - حاسبة الأشكال8مفاهيم البرمجة كائنية التوجه (OOP) المتقدمة
التركيب بدلاً من الوراثةالـ Generics (الأصناف والدوال)الـ Delegates والأحداثالـ Attributes والـ Reflectionواجهة IDisposable وجملة usingأساسيات Dependency Injection