Menu
Coddy logo textTech

פיתוח דמות במשחק

חלק מהיחידה תכנות מונחה עצמים במסלול ה-PHP של Coddy. שיעור 90 מתוך 91.

challenge icon

אתגר

קל

בוא נבנה מערכת פיתוח דמויות במשחק, שבה מחלקות דמויות שונות נלחמות באמצעות יכולות ייחודיות. תיצור היררכיית דמויות עם מערכת ניסיון ועליית רמות, ותראה כיצד ירושה, ממשקים, תכונות וכימוס פועלים יחד בהקשר של משחק.

תארגן את הקוד שלך בשישה קבצים:

  • Ability.php: הגדר ממשק Ability עם שתי מתודות: getName(): string ו-use(Character $target): string. חוזה זה מבטיח שניתן יהיה להשתמש בכל היכולות באופן עקבי, ללא קשר להשפעות הספציפיות שלהן.
  • CombatLogger.php: צור תכונה CombatLogger שמספקת מתודה logAction(string $action): string. המתודה צריכה להחזיר את מחרוזת הפעולה עם הקידומת "[COMBAT] ". דמויות ישתמשו בתכונה הזאת כדי לעצב את הודעות הקרב שלהן באופן עקבי.
  • Character.php: כלול את הקבצים Ability ו-CombatLogger. צור מחלקה מופשטת Character שמשתמשת בתכונה CombatLogger. השתמש בקידום מאפיינים בבנאי עבור name (מחרוזת, public readonly). כלול מאפיינים פרטיים עבור health (מספר שלם, מתחיל ב-100), level (מספר שלם, מתחיל ב-1) ו-experience (מספר שלם, מתחיל ב-0). ממש את:
    • getHealth(): int ו-getLevel(): int: מאחזרות את המאפיינים הפרטיים
    • takeDamage(int $amount): void: מפחיתה את הבריאות, אך לעולם לא מתחת ל-0
    • heal(int $amount): void: מגדילה את הבריאות, אך לעולם לא מעל 100
    • gainExperience(int $xp): string: מוסיפה XP; אם הניסיון מגיע ל-100 או יותר, הדמות עולה רמה (איפוס XP ל-0, הגדלת הרמה, ריפוי של 20 HP), ומחזירה "[name] leveled up to [level]!"; אחרת מחזירה "[name] gained [xp] XP"
    • isAlive(): bool: מחזירה true אם הבריאות גדולה מ-0
    • abstract getSpecialAbility(): Ability: כל סוג דמות מספק את היכולת הייחודית שלו
    • attack(Character $target): string: גורמת נזק של 10 למטרה, משתמשת ב-logAction() כדי להחזיר "[COMBAT] [name] attacks [target name] for 10 damage"
  • Warrior.php: כלול את קובץ Character. צור מחלקה Warrior שיורשת מ-Character. ממש את getSpecialAbility() כך שתחזיר מחלקה אנונימית שמממשת את Ability:
    • getName() מחזירה "Shield Bash"
    • use() גורמת נזק של 25 ומחזירה "[COMBAT] Shield Bash hits [target name] for 25 damage!" (השתמש בתכונה logAction())
  • Mage.php: כלול את קובץ Character. צור מחלקה Mage שיורשת מ-Character. ממש את getSpecialAbility() כך שתחזיר מחלקה אנונימית שמממשת את Ability:
    • getName() מחזירה "Fireball"
    • use() גורמת נזק של 35 ומחזירה "[COMBAT] Fireball engulfs [target name] for 35 damage!"
  • main.php: כלול את הקבצים Warrior ו-Mage. יתקבלו שתי קלטים: נתוני הדמויות (JSON) ורצף של פעולות קרב (JSON).

    מבנה JSON של הדמויות:

    [{"type": "warrior", "name": "Thorin"}, {"type": "mage", "name": "Gandalf"}]

    מבנה JSON של הפעולות:

    [{"action": "attack", "attacker": 0, "target": 1}, {"action": "special", "attacker": 1, "target": 0}, {"action": "xp", "character": 0, "amount": 100}, {"action": "status", "character": 0}]

    צור את כל הדמויות ושמור אותן במערך (אינדקס 0, 1 וכן הלאה). עבד כל פעולה:

    • "attack": הדמות שבאינדקס התוקף תוקפת את המטרה; הדפס את התוצאה
    • "special": הדמות משתמשת ביכולת המיוחדת שלה נגד המטרה; הדפס את התוצאה
    • "xp": הדמות צוברת ניסיון; הדפס את התוצאה
    • "heal": הדמות מתרפאת בכמות הנתונה; הדפס "[name] healed to [health] HP"
    • "status": הדפס "[name] - Level [level], HP: [health], Alive: [Yes/No]"

    הדפס כל תוצאה בשורה חדשה.

המערכת הזאת מדגימה כיצד מחלקות מופשטות מגדירות התנהגות משותפת לדמויות, ממשקים מבטיחים שהיכולות יעמדו בחוזה אחיד, תכונות מספקות פונקציונליות רישום חוזרת לשימוש, ומחלקות אנונימיות מאפשרות ליצור מימושים ייחודיים של יכולות בלי להעמיס על בסיס הקוד במחלקות לשימוש חד-פעמי.

נסו בעצמכם

<?php
require_once 'Warrior.php';
require_once 'Mage.php';

// קראו את הקלט
$charactersJson = trim(fgets(STDIN));
$actionsJson = trim(fgets(STDIN));

// פענחו את קלטי ה-JSON
$charactersData = (array)json_decode($charactersJson, true);
$actionsData = (array)json_decode($actionsJson, true);

// TODO: צרו מערך לאחסון אובייקטים של דמויות
$characters = [];

// TODO: עברו על $charactersData וצרו אובייקטים מסוג Warrior או Mage
// בהתאם לשדה "type", ואחסנו אותם במערך $characters

// TODO: עבדו כל פעולה ב-$actionsData
// טפלו בסוגי הפעולות הבאים:
// - "attack": הדמות באינדקס התוקף תוקפת את המטרה; הדפיסו את התוצאה
// - "special": הדמות משתמשת ב-getSpecialAbility()->use() על המטרה; הדפיסו את התוצאה
// - "xp": הדמות צוברת ניסיון; הדפיסו את התוצאה
// - "heal": הדמות מתרפאת; הדפיסו "[name] healed to [health] HP"
// - "status": הדפיסו "[name] - Level [level], HP: [health], Alive: [Yes/No]"

?>

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר PHP אונליין