Tworzenie postaci do gry
Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 90 z 91.
Wyzwanie
ŁatwyZbudujmy system Rozwoju postaci w grze, w którym różne klasy postaci walczą, używając unikalnych zdolności. Stworzysz hierarchię postaci z systemem doświadczenia i awansowania na kolejne poziomy, pokazując, jak dziedziczenie, interfejsy, cechy i enkapsulacja współdziałają w kontekście gry.
Rozmieścisz kod w sześciu plikach:
Ability.php: Zdefiniuj interfejsAbilityz dwiema metodami:getName(): stringiuse(Character $target): string. Ten kontrakt zapewnia, że wszystkie zdolności można stosować w spójny sposób, niezależnie od ich konkretnych efektów.CombatLogger.php: Utwórz cechęCombatLogger, która udostępnia metodęlogAction(string $action): string. Metoda ta powinna zwracać ciąg znaków opisujący akcję z prefiksem"[COMBAT] ". Postacie będą używać tej cechy, aby formatować komunikaty dotyczące walki w spójny sposób.Character.php: Dołącz pliki Ability i CombatLogger. Utwórz abstrakcyjną klasęCharacter, która używa cechyCombatLogger. Użyj promocji konstruktora dlaname(string, public readonly). Dodaj prywatne właściwości:health(int, początkowo 100),level(int, początkowo 1) orazexperience(int, początkowo 0). Zaimplementuj:getHealth(): intigetLevel(): int: metody pobierające wartości prywatnych właściwościtakeDamage(int $amount): void: zmniejsza zdrowie, ale nigdy poniżej 0heal(int $amount): void: zwiększa zdrowie, ale nigdy powyżej 100gainExperience(int $xp): string: dodaje PD; jeśli doświadczenie osiągnie co najmniej 100, postać awansuje na kolejny poziom (ustawia PD na 0, zwiększa poziom, przywraca 20 HP) i zwraca"[name] leveled up to [level]!"; w przeciwnym razie zwraca"[name] gained [xp] XP"isAlive(): bool: zwraca true, jeśli zdrowie jest większe niż 0abstract getSpecialAbility(): Ability: każdy typ postaci udostępnia swoją unikalną zdolnośćattack(Character $target): string: zadaje celowi 10 punktów obrażeń, używalogAction(), aby zwrócić"[COMBAT] [name] attacks [target name] for 10 damage"
Warrior.php: Dołącz plik Character. Utwórz klasęWarriorrozszerzającąCharacter. ZaimplementujgetSpecialAbility(), aby zwracała klasę anonimową implementującąAbility:getName()zwraca"Shield Bash"use()zadaje 25 punktów obrażeń i zwraca"[COMBAT] Shield Bash hits [target name] for 25 damage!"(użyj metodylogAction()z cechy)
Mage.php: Dołącz plik Character. Utwórz klasęMagerozszerzającąCharacter. ZaimplementujgetSpecialAbility(), aby zwracała klasę anonimową implementującąAbility:getName()zwraca"Fireball"use()zadaje 35 punktów obrażeń i zwraca"[COMBAT] Fireball engulfs [target name] for 35 damage!"
main.php: Dołącz pliki Warrior i Mage. Otrzymasz dwa wejścia: dane postaci (JSON) i sekwencję akcji bojowych (JSON).Format JSON postaci:
[{"type": "warrior", "name": "Thorin"}, {"type": "mage", "name": "Gandalf"}]Format JSON akcji:
[{"action": "attack", "attacker": 0, "target": 1}, {"action": "special", "attacker": 1, "target": 0}, {"action": "xp", "character": 0, "amount": 100}, {"action": "status", "character": 0}]Utwórz wszystkie postacie i przechowaj je w tablicy (indeksy 0, 1 itd.). Przetwórz każdą akcję:
"attack": postać o indeksie attacker atakuje cel; wypisz wynik"special": postać używa swojej specjalnej zdolności na celu; wypisz wynik"xp": postać zdobywa doświadczenie; wypisz wynik"heal": postać odzyskuje zdrowie o podaną wartość; wypisz"[name] healed to [health] HP""status": wypisz"[name] - Level [level], HP: [health], Alive: [Yes/No]"
Wypisz każdy wynik w nowym wierszu.
Ten system pokazuje, jak klasy abstrakcyjne definiują wspólne zachowania postaci, interfejsy zapewniają zgodność zdolności ze spójnym kontraktem, cechy udostępniają funkcjonalność rejestrowania możliwą do ponownego użycia, a klasy anonimowe pozwalają tworzyć unikalne implementacje zdolności bez zaśmiecania bazy kodu klasami używanymi tylko raz.
Spróbuj swoich sił
<?php
require_once 'Warrior.php';
require_once 'Mage.php';
// Odczytaj dane wejściowe
$charactersJson = trim(fgets(STDIN));
$actionsJson = trim(fgets(STDIN));
// Przetwórz dane wejściowe JSON
$charactersData = (array)json_decode($charactersJson, true);
$actionsData = (array)json_decode($actionsJson, true);
// TODO: Utwórz tablicę do przechowywania obiektów postaci
$characters = [];
// TODO: Przejdź przez $charactersData i utwórz obiekty Warrior lub Mage
// na podstawie pola "type", a następnie zapisz je w tablicy $characters
// TODO: Przetwórz każdą akcję w $actionsData
// Obsłuż następujące typy akcji:
// - "attack": Postać o indeksie atakującego atakuje cel; wypisz wynik
// - "special": Postać używa getSpecialAbility()->use() na celu; wypisz wynik
// - "xp": Postać zdobywa doświadczenie; wypisz wynik
// - "heal": Postać się leczy; wypisz "[name] healed to [health] HP"
// - "status": Wypisz "[name] - Level [level], HP: [health], Alive: [Yes/No]"
?>Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneWprowadzenie do programowania obiektowegoKlasy a obiektySłowo kluczowe $thisMetodyWłaściwościKonstruktor (__construct)Destruktor (__destruct)Powtórka — prosty kalkulator4Dziedziczenie
Podstawy dziedziczeniaSłowo kluczowe parent::Przesłanianie metodSłowo kluczowe finalKlasy abstrakcyjnePowtórzenie – hierarchia pracowników7Enkapsulacja
Public, protected, privateModyfikatory dostępu w szczegółachGettery i setteryUkrywanie informacjiPromocja parametrów konstruktora (8.0)Podsumowanie — system ewidencji studentów2Przestrzenie nazw i autoloading
Wprowadzenie do przestrzeni nazwSłowo kluczowe useStandard autoloadingu PSR-4Autoloader ComposeraPodsumowanie – uporządkowany projekt5Interfejsy i kontrakty
Wprowadzenie do interfejsówImplementowanie interfejsówImplementowanie wielu interfejsówInterfejs a klasa abstrakcyjnaPodpowiadanie typów za pomocą interfejsówPodsumowanie — kalkulator kształtów8Metody magiczne
Wprowadzenie do metod magicznych__toString i __debugInfo__get, __set, __isset, __unset__call i __callStatic__clone i klonowanie obiektów__serialize i __unserializePodsumowanie — własna kolekcja11System typów i obsługa błędów
Deklaracje typówTypy nullableTypy sumy i przecięciaKlasy wyjątkówNiestandardowa hierarchia wyjątkówTry, Catch, FinallyPodsumowanie — walidator formularzy14Projekt: Zarządzanie biblioteką
Przegląd projektuKlasy książki i użytkownika3Właściwości klas
Właściwości instancji a właściwości statyczneStałe w klasachMetody i właściwości statyczneWłaściwości prywatne i chronioneWłaściwości tylko do odczytu (PHP 8.1)Podsumowanie — menedżer kont bankowych6Polimorfizm
Ponowne omówienie nadpisywania metodPolimorfizm za pomocą interfejsówPodpowiedzi typów i typy sumyPóźne wiązanie statycznePodsumowanie — procesor płatności9Cechy
Wprowadzenie do cechKorzystanie z wielu cechRozwiązywanie konfliktów cechMetody abstrakcyjne w cechachCechy a dziedziczenie12Wzorce projektowe, część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec ObserverWzorzec Strategy15Wyzwania końcowe
Platforma e-learningowaSystem bankowyTworzenie postaci do gryUsługa wynajmu pojazdówPoćwicz samodzielnie: Kompilator PHP online