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

تطوير شخصيات الألعاب

جزء من قسم البرمجة كائنية التوجه في رحلة Java على Coddy. الدرس 86 من 87.

يتحداك هذا التمرين لبناء نظام تطوير شخصيات اللعبة يبرز قوة البرمجة كائنية التوجه في نمذجة الكيانات المعقدة والتفاعلية.

صمّم تسلسلًا هرميًا للشخصيات، حيث تحدد الفئة الأساسية Character سمات مشتركة مثل الصحة والاسم والمستوى. وتمتد الفئات المتخصصة مثل Warrior وMage وArcher من هذه الفئة الأساسية بقدرات وأساليب قتال فريدة.

تعمل الواجهات بشكل طبيعي هنا: يمكن أن تحدد Attackable أساليب القتال، بينما تتولى Healable قدرات الاستعادة. وقد تطبّق Mage كليهما، في حين يركّز Warrior على الهجوم فقط.

فكّر في استخدام نمط Strategy لسلوكيات الهجوم المختلفة، مما يتيح للشخصيات تبديل أساليب combat ديناميكيًا. ويمكن لنمط State إدارة حالات character مثل الحالات العادية أو المسمومة أو المذهولة التي تؤثر في السلوك.

فكّر في التركيب لأنظمة المعدات، حيث تمتلك characters الأسلحة والدروع بدلًا من أن ترث منها. استخدم التعدادات لفئات class أو أنواع الضرر، وطبّق التغليف لحماية الإحصاءات من التعديلات غير الصالحة.

challenge icon

التحدي

سهل

لنُنشئ نظامًا لتطوير شخصيات لعبة يستعرض قوة البرمجة كائنية التوجه في نمذجة كيانات الألعاب المعقدة والتفاعلية! ستنشئ تسلسلًا هرميًا للشخصيات يتضمن أساليب قتال مختلفة، وقدرات خاصة، ونظام حالات يؤثر في كيفية تصرف الشخصيات.

ستنظم شيفرتك عبر سبعة ملفات:

  • DamageType.java: أنشئ تعدادًا يمثل أنواع الضرر المختلفة في اللعبة. ضمّن القيم PHYSICAL وMAGICAL وRANGED. أضف حقلًا خاصًا description من النوع String، وبانيًا يعيّنه، ودالة getter. يجب أن يكون وصف الضرر الجسدي "brute force"، والضرر السحري "arcane energy"، والضرر بعيد المدى "precision strike".
  • Attackable.java: أنشئ واجهةً تحدد إمكانات القتال. صرّح بالدوال attack(Character target) التي تُرجع قيمة String تصف الهجوم، وgetDamageType() التي تُرجع قيمة من النوع DamageType.
  • Healable.java: أنشئ واجهةً لقدرات الاستعادة. صرّح بدالة heal(int amount) التي تُرجع قيمة String تصف إجراء التعافي.
  • Character.java: أنشئ فئةً أساسيةً مجردةً لجميع شخصيات اللعبة. ضمّن حقولًا خاصةً لـ name من النوع String، وhealth من النوع int، وmaxHealth من النوع int، وlevel من النوع int. يأخذ الباني name وmaxHealth وlevel، ويضبط health مساويًا لـ maxHealth مبدئيًا. ضمّن دوال getter لجميع الحقول. أضف دالة محمية setHealth(int health) تضمن بقاء health بين 0 وmaxHealth. أنشئ دالة takeDamage(int damage) تقلل health وتُرجع "[name] takes [damage] damage! Health: [health]/[maxHealth]". أضف دالة isAlive() تُرجع true إذا كانت health أكبر من 0. صرّح بدالة مجردة getCharacterClass() تُرجع قيمة من النوع String.
  • Warrior.java: أنشئ فئةً تمتد من Character وتطبّق Attackable. أضف حقلًا خاصًا strength من النوع int. يأخذ الباني name وmaxHealth وlevel وstrength. طبّق getCharacterClass() لإرجاع "Warrior". طبّق getDamageType() لإرجاع PHYSICAL. طبّق attack(Character target) لإحداث ضرر يساوي strength زائد level، واستدعاء دالة takeDamage الخاصة بالهدف، وإرجاع "[name] strikes with [damageType description] for [damage] damage!" متبوعًا بسطر جديد ونتيجة takeDamage.
  • Mage.java: أنشئ فئةً تمتد من Character وتطبّق كلًا من Attackable وHealable. أضف حقلين خاصين هما intelligence من النوع int وmana من النوع int. يأخذ الباني name وmaxHealth وlevel وintelligence وmana. طبّق getCharacterClass() لإرجاع "Mage". طبّق getDamageType() لإرجاع MAGICAL. طبّق attack(Character target) لإحداث ضرر يساوي intelligence مضروبًا في 2، باتباع التنسيق نفسه الخاص بـ Warrior. طبّق heal(int amount) لاستعادة health (باستخدام setHealth) وإرجاع "[name] channels healing magic! Health: [health]/[maxHealth]".
  • Main.java: اجعل نظام لعبتك ينبض بالحياة! ستتلقى سلسلة أوامر مفصولة بفواصل:
    • CREATE_WARRIOR:name:maxHealth:level:strength
    • CREATE_MAGE:name:maxHealth:level:intelligence:mana
    • ATTACK:attackerName:targetName
    • HEAL:mageName:amount
    • STATUS:characterName

    احتفظ بمجموعة من الشخصيات. عالج كل أمر واطبع:

    • CREATE_WARRIOR/CREATE_MAGE: [name] the [characterClass] joins the battle!
    • ATTACK: اطبع نتيجة الهجوم (قيمة String المُرجعة من دالة attack)
    • HEAL: اطبع نتيجة التعافي، أو [name] cannot heal إذا لم تكن الشخصية Mage
    • STATUS: [name] ([characterClass]) - Level [level] - Health: [health]/[maxHealth] - [Alive/Defeated]

    بعد جميع الأوامر، اطبع --- Battle Summary --- متبوعًا بحالة كل شخصية.

ستتلقى إدخالًا واحدًا: سلسلة الأوامر المفصولة بفواصل.

على سبيل المثال، عند استخدام الإدخال CREATE_WARRIOR:Thorin:100:5:15,CREATE_MAGE:Gandalf:80:7:12:50,ATTACK:Thorin:Gandalf,HEAL:Gandalf:25,STATUS:Gandalf، سيكون ناتجك:

Thorin the Warrior joins the battle!
Gandalf the Mage joins the battle!
Thorin strikes with brute force for 20 damage!
Gandalf takes 20 damage! Health: 60/80
Gandalf channels healing magic! Health: 80/80
Gandalf (Mage) - Level 7 - Health: 80/80 - Alive
--- Battle Summary ---
Thorin (Warrior) - Level 5 - Health: 100/100 - Alive
Gandalf (Mage) - Level 7 - Health: 80/80 - Alive

يجمع هذا التحدي بين الوراثة (التسلسل الهرمي لـ Character)، وتطبيق واجهات متعددة (يطبّق Mage كلًا من Attackable وHealable)، والتعدادات ذات الدوال (DamageType)، وتعدد الأشكال (التعامل مع أنواع الشخصيات المختلفة بطريقة موحّدة)، والتغليف (إدارة health المحمية) ضمن نظام لعبة تفاعلي!

جرّب بنفسك

import java.util.Scanner;
import java.util.HashMap;
import java.util.Map;
import java.util.LinkedHashMap;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();
        
        // TODO: استخدم مجموعة لإدارة الشخصيات (يحافظ LinkedHashMap على ترتيب الإدخال)
        // LinkedHashMap<String, Character> characters = new LinkedHashMap<>();
        
        // TODO: قم بتقسيم الإدخال بواسطة الفاصلة للحصول على الأوامر الفردية
        // String[] commands = input.split(",");
        
        // TODO: معالجة كل أمر:
        // - CREATE_WARRIOR:name:maxHealth:level:strength
        //   Print: "[name] the Warrior joins the battle!"
        // 
        // - CREATE_MAGE:name:maxHealth:level:intelligence:mana
        //   Print: "[name] the Mage joins the battle!"
        // 
        // - ATTACK:attackerName:targetName
        //   اطبع نتيجة الهجوم من دالة attack
        // 
        // - HEAL:mageName:amount
        //   اطبع نتيجة العلاج، أو "[name] cannot heal" إذا لم يكن Mage
        // 
        // - STATUS:characterName
        //   اطبع: "[name] ([characterClass]) - Level [level] - Health: [health]/[maxHealth] - [Alive/Defeated]"
        
        // TODO: After all commands, print "--- Battle Summary ---"
        // ثم اطبع حالة كل شخصية
    }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم Java عبر الإنترنت