Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

مكون شخصية اللعبة

جزء من قسم Object Oriented Programming في رحلة C# على Coddy — الدرس 69 من 70.

challenge icon

التحدي

سهل

لنقم ببناء نظام شخصيات ألعاب باستخدام نمط الهندسة القائم على المكونات (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