Menu
Coddy logo textTech

Sviluppo di un personaggio di gioco

Fa parte della sezione Programmazione orientata agli oggetti del percorso PHP di Coddy. Lezione 90 di 91.

challenge icon

Sfida

Facile

Costruiamo un sistema di Sviluppo dei personaggi di gioco in cui diverse classi di personaggi combattono usando abilità uniche. Creerai una gerarchia di personaggi con un sistema di esperienza e avanzamento di livello, dimostrando come ereditarietà, interfacce, trait e incapsulamento collaborino nel contesto di un gioco.

Organizzerai il codice in sei file:

  • Ability.php: definisci un'interfaccia Ability con due metodi: getName(): string e use(Character $target): string. Questo contratto garantisce che tutte le abilità possano essere usate in modo coerente, indipendentemente dai loro effetti specifici.
  • CombatLogger.php: crea un trait CombatLogger che fornisce un metodo logAction(string $action): string. Questo metodo deve restituire la stringa dell'azione preceduta da "[COMBAT] ". I personaggi useranno questo trait per formattare in modo coerente i loro messaggi di combattimento.
  • Character.php: includi i file Ability e CombatLogger. Crea una classe astratta Character che usa il trait CombatLogger. Usa la promozione dei parametri del costruttore per name (string, public readonly). Includi le proprietà private health (int, inizializzata a 100), level (int, inizializzata a 1) e experience (int, inizializzata a 0). Implementa:
    • getHealth(): int e getLevel(): int: getter per le proprietà private
    • takeDamage(int $amount): void: riduce la salute, senza mai scendere sotto 0
    • heal(int $amount): void: aumenta la salute, senza mai superare 100
    • gainExperience(int $xp): string: aggiunge XP; se l'esperienza raggiunge o supera 100, avanza di livello (azzera gli XP, aumenta il livello, ripristina 20 HP), restituisci "[name] leveled up to [level]!"; altrimenti restituisci "[name] gained [xp] XP"
    • isAlive(): bool: restituisce true se la salute è maggiore di 0
    • abstract getSpecialAbility(): Ability: ogni tipo di personaggio fornisce la propria abilità unica
    • attack(Character $target): string: infligge 10 danni al bersaglio, usa logAction() per restituire "[COMBAT] [name] attacks [target name] for 10 damage"
  • Warrior.php: includi il file Character. Crea una classe Warrior che estende Character. Implementa getSpecialAbility() in modo che restituisca una classe anonima che implementa Ability:
    • getName() restituisce "Shield Bash"
    • use() infligge 25 danni e restituisce "[COMBAT] Shield Bash hits [target name] for 25 damage!" (usa il logAction() del trait)
  • Mage.php: includi il file Character. Crea una classe Mage che estende Character. Implementa getSpecialAbility() in modo che restituisca una classe anonima che implementa Ability:
    • getName() restituisce "Fireball"
    • use() infligge 35 danni e restituisce "[COMBAT] Fireball engulfs [target name] for 35 damage!"
  • main.php: includi i file Warrior e Mage. Riceverai due input: i dati dei personaggi (JSON) e una sequenza di azioni di combattimento (JSON).

    Formato JSON dei personaggi:

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

    Formato JSON delle azioni:

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

    Crea tutti i personaggi e memorizzali in un array (indice 0, 1 e così via). Elabora ogni azione:

    • "attack": il personaggio all'indice attacker attacca il bersaglio; stampa il risultato
    • "special": il personaggio usa la propria abilità speciale sul bersaglio; stampa il risultato
    • "xp": il personaggio guadagna esperienza; stampa il risultato
    • "heal": il personaggio recupera salute in base alla quantità indicata; stampa "[name] healed to [health] HP"
    • "status": stampa "[name] - Level [level], HP: [health], Alive: [Yes/No]"

    Stampa ogni risultato su una nuova riga.

Questo sistema dimostra come le classi astratte definiscano il comportamento condiviso dei personaggi, le interfacce garantiscano che le abilità rispettino un contratto coerente, i trait forniscano funzionalità di registrazione riutilizzabili e le classi anonime permettano di creare implementazioni di abilità uniche senza appesantire il codice con classi usate una sola volta.

Provalo tu

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

// Leggi l'input
$charactersJson = trim(fgets(STDIN));
$actionsJson = trim(fgets(STDIN));

// Analizza gli input JSON
$charactersData = (array)json_decode($charactersJson, true);
$actionsData = (array)json_decode($actionsJson, true);

// TODO: Crea un array per memorizzare gli oggetti dei personaggi
$characters = [];

// TODO: Scorri $charactersData e crea oggetti Warrior o Mage
// in base al campo "type" e memorizzali nell'array $characters

// TODO: Elabora ogni azione in $actionsData
// Gestisci questi tipi di azione:
// - "attack": Il personaggio all'indice dell'attaccante attacca il bersaglio; stampa il risultato
// - "special": Il personaggio usa getSpecialAbility()->use() sul bersaglio; stampa il risultato
// - "xp": Il personaggio guadagna esperienza; stampa il risultato
// - "heal": Il personaggio si cura; stampa "[name] healed to [health] HP"
// - "status": Stampa "[name] - Level [level], HP: [health], Alive: [Yes/No]"

?>

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore PHP online