Entwicklung einer Spielfigur
Teil des Abschnitts Objektorientierte Programmierung der PHP-Journey von Coddy. Lektion 90 von 91.
Aufgabe
EinfachLass uns ein Game Character Development-System erstellen, in dem verschiedene Charakterklassen mit einzigartigen Fähigkeiten gegeneinander kämpfen. Du erstellst eine Hierarchie von Charakteren mit einem Erfahrungs- und Levelsystem und demonstrierst dabei, wie Vererbung, Interfaces, Traits und Kapselung in einem Spielkontext zusammenwirken.
Du organisierst deinen Code über sechs Dateien:
Ability.php: Definiere einAbility-Interface mit zwei Methoden:getName(): stringunduse(Character $target): string. Dieser Vertrag stellt sicher, dass alle Fähigkeiten unabhängig von ihren spezifischen Effekten einheitlich verwendet werden können.CombatLogger.php: Erstelle einCombatLogger-Trait, das einelogAction(string $action): string-Methode bereitstellt. Diese Methode soll den Aktions-String mit dem Präfix"[COMBAT] "zurückgeben. Charaktere verwenden dieses Trait, um ihre Kampfnachrichten einheitlich zu formatieren.Character.php: Binde die Dateien Ability und CombatLogger ein. Erstelle eine abstrakteCharacter-Klasse, die dasCombatLogger-Trait verwendet. Verwende Constructor Promotion fürname(string, public readonly). Füge private Eigenschaften fürhealth(int, beginnend bei 100),level(int, beginnend bei 1) undexperience(int, beginnend bei 0) hinzu. Implementiere:getHealth(): intundgetLevel(): int: Getter für die privaten EigenschaftentakeDamage(int $amount): void: reduziert die Gesundheit, aber niemals unter 0heal(int $amount): void: erhöht die Gesundheit, aber niemals über 100gainExperience(int $xp): string: fügt XP hinzu; wenn die Erfahrung 100 oder mehr erreicht, steigt der Charakter ein Level auf (XP auf 0 zurücksetzen, Level erhöhen, 20 HP heilen), und"[name] leveled up to [level]!"wird zurückgegeben; andernfalls wird"[name] gained [xp] XP"zurückgegebenisAlive(): bool: gibt true zurück, wenn die Gesundheit größer als 0 istabstract getSpecialAbility(): Ability: jeder Charaktertyp stellt seine einzigartige Fähigkeit bereitattack(Character $target): string: verursacht beim Ziel 10 Schaden und verwendetlogAction(), um"[COMBAT] [name] attacks [target name] for 10 damage"zurückzugeben
Warrior.php: Binde die Character-Datei ein. Erstelle eineWarrior-Klasse, dieCharactererweitert. ImplementieregetSpecialAbility(), sodass eine anonyme Klasse zurückgegeben wird, dieAbilityimplementiert:getName()gibt"Shield Bash"zurückuse()verursacht 25 Schaden und gibt"[COMBAT] Shield Bash hits [target name] for 25 damage!"zurück (verwende daslogAction()des Traits)
Mage.php: Binde die Character-Datei ein. Erstelle eineMage-Klasse, dieCharactererweitert. ImplementieregetSpecialAbility(), sodass eine anonyme Klasse zurückgegeben wird, dieAbilityimplementiert:getName()gibt"Fireball"zurückuse()verursacht 35 Schaden und gibt"[COMBAT] Fireball engulfs [target name] for 35 damage!"zurück
main.php: Binde die Warrior- und Mage-Dateien ein. Du erhältst zwei Eingaben: Charakterdaten (JSON) und eine Abfolge von Kampfaktionen (JSON).JSON-Format der Charaktere:
[{"type": "warrior", "name": "Thorin"}, {"type": "mage", "name": "Gandalf"}]JSON-Format der Aktionen:
[{"action": "attack", "attacker": 0, "target": 1}, {"action": "special", "attacker": 1, "target": 0}, {"action": "xp", "character": 0, "amount": 100}, {"action": "status", "character": 0}]Erstelle alle Charaktere und speichere sie in einem Array (Index 0, 1 usw.). Verarbeite jede Aktion:
"attack": Der Charakter am Angreifer-Index greift das Ziel an; gib das Ergebnis aus"special": Der Charakter verwendet seine Spezialfähigkeit auf das Ziel; gib das Ergebnis aus"xp": Der Charakter sammelt Erfahrung; gib das Ergebnis aus"heal": Der Charakter heilt sich um den angegebenen Betrag; gib"[name] healed to [health] HP"aus"status": Gib"[name] - Level [level], HP: [health], Alive: [Yes/No]"aus
Gib jedes Ergebnis in einer neuen Zeile aus.
Dieses System zeigt, wie abstrakte Klassen gemeinsames Charakterverhalten definieren, Interfaces sicherstellen, dass Fähigkeiten einem einheitlichen Vertrag folgen, Traits wiederverwendbare Protokollierungsfunktionen bereitstellen und anonyme Klassen einzigartige Fähigkeitsimplementierungen erstellen, ohne deine Codebasis mit nur einmal verwendeten Klassen zu überladen.
Probier es selbst
<?php
require_once 'Warrior.php';
require_once 'Mage.php';
// Eingabe lesen
$charactersJson = trim(fgets(STDIN));
$actionsJson = trim(fgets(STDIN));
// JSON-Eingaben parsen
$charactersData = (array)json_decode($charactersJson, true);
$actionsData = (array)json_decode($actionsJson, true);
// TODO: Erstelle ein Array zum Speichern von Charakterobjekten
$characters = [];
// TODO: Durchlaufe $charactersData und erstelle Warrior- oder Mage-Objekte
// basierend auf dem "type"-Feld, speichere sie im $characters-Array
// TODO: Verarbeite jede Aktion in $actionsData
// Behandle diese Aktionstypen:
// - "attack": Charakter am Angreifer-Index greift Ziel an; Ergebnis ausgeben
// - "special": Charakter verwendet getSpecialAbility()->use() auf das Ziel; Ergebnis ausgeben
// - "xp": Charakter erhält Erfahrung; Ergebnis ausgeben
// - "heal": Charakter heilt; gib "[name] healed to [health] HP" aus
// - "status": Gib "[name] - Level [level], HP: [health], Alive: [Yes/No]" aus
?>Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in OOPKlassen vs. ObjekteDas Schlüsselwort $thisMethodenEigenschaftenKonstruktor (__construct)Destruktor (__destruct)Rückblick – Einfacher Taschenrechner4Vererbung
Grundlegende VererbungDas Schlüsselwort parent::MethodenüberschreibungDas Schlüsselwort finalAbstrakte KlassenRückblick – Mitarbeiterhierarchie7Kapselung
Öffentlich, geschützt, privatZugriffsmodifikatoren im DetailGetter und SetterInformationsverbergungKonstruktor-Promotion (8.0)Wiederholung – System zur Verwaltung von Schülerdatensätzen2Namespaces & Autoloading
Einführung in NamespacesDas use-SchlüsselwortPSR-4-Autoloading-StandardComposer-AutoloaderRückblick – Organisiertes Projekt5Schnittstellen & Verträge
Einführung in SchnittstellenSchnittstellen implementierenMehrere Schnittstellen implementierenSchnittstelle vs. abstrakte KlasseTyp-Hinweise mit SchnittstellenRückblick – Formrechner8Magische Methoden
Einführung in magische Methoden__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Objektklonen__serialize & __unserializeRückblick – Benutzerdefinierte Sammlung11Typsystem & Fehlerbehandlung
TypdeklarationenNullable-TypenUnion- & Intersection-TypenException-KlassenBenutzerdefinierte Exception-HierarchieTry, Catch, FinallyRückblick – Formularvalidator14Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen3Klassen-Eigenschaften
Instanz- vs. statische EigenschaftenKonstanten in KlassenStatische Methoden & EigenschaftenPrivate & geschützte EigenschaftenSchreibgeschützte Eigenschaften (PHP 8.1)Zusammenfassung – Bankkonto-Manager6Polymorphie
Methodenüberschreibung erneut betrachtetPolymorphie über SchnittstellenTyp-Hinweise & Union-TypenSpätes statisches BindenRückblick – Zahlungsabwickler9Traits
Einführung in TraitsMehrere Traits verwendenAuflösung von Trait-KonfliktenAbstrakte Methoden in TraitsTraits vs. Vererbung12Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster15Abschließende Herausforderungen
E-Learning-PlattformBankingsystemEntwicklung einer SpielfigurFahrzeugvermietungÜbe selbstständig: Online-PHP-Compiler