Menu
Coddy logo textTech

Tworzenie postaci do gry

Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 86 z 87.

To wyzwanie polega na zbudowaniu systemu rozwoju postaci w grze, który pokazuje możliwości programowania obiektowego w modelowaniu złożonych, interaktywnych bytów.

Stwórz hierarchię postaci, w której bazowa klasa Character definiuje wspólne atrybuty, takie jak zdrowie, imię i poziom. Wyspecjalizowane klasy, takie jak Warrior, Mage i Archer, rozszerzają tę bazę o unikalne umiejętności i style walki.

Interfejsy sprawdzają się tu naturalnie: Attackable może definiować metody walki, a Healable obsługiwać zdolności przywracania zdrowia. Mage może implementować oba interfejsy, podczas gdy Warrior skupia się wyłącznie na atakowaniu.

Rozważ użycie wzorca Strategia dla różnych zachowań związanych z atakiem, aby postacie mogły dynamicznie zmieniać style walki. Wzorzec Stan mógłby zarządzać stanami postaci, takimi jak normalny, zatruty lub ogłuszony, które wpływają na zachowanie.

Pomyśl o kompozycji w systemach wyposażenia, w których postacie „mają” broń i zbroję, zamiast po nich dziedziczyć. Używaj wyliczeń dla klas postaci lub typów obrażeń i stosuj enkapsulację, aby chronić statystyki przed nieprawidłowymi modyfikacjami.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system rozwoju postaci w grze, który pokazuje możliwości programowania obiektowego w modelowaniu złożonych, interaktywnych postaci! Stworzysz hierarchię postaci o różnych stylach walki, specjalnych zdolnościach i systemie stanu, który wpływa na zachowanie postaci.

Rozmieścisz swój kod w siedmiu plikach:

  • DamageType.java: Utwórz typ wyliczeniowy reprezentujący różne rodzaje obrażeń w grze. Uwzględnij wartości PHYSICAL, MAGICAL i RANGED. Dodaj prywatne pole description (String), konstruktor, który je ustawia, oraz metodę pobierającą. Obrażenia fizyczne powinny mieć opis "brute force", magiczne — "arcane energy", a dystansowe — "precision strike".
  • Attackable.java: Utwórz interfejs określający możliwości walki. Zadeklaruj metody attack(Character target), która zwraca String opisujący atak, oraz getDamageType(), która zwraca DamageType.
  • Healable.java: Utwórz interfejs dla zdolności przywracania zdrowia. Zadeklaruj metodę heal(int amount), która zwraca String opisujący leczenie.
  • Character.java: Utwórz abstrakcyjną klasę bazową dla wszystkich postaci w grze. Uwzględnij prywatne pola: name (String), health (int), maxHealth (int) i level (int). Konstruktor przyjmuje name, maxHealth i level, a początkowo ustawia health na wartość maxHealth. Dodaj metody pobierające dla wszystkich pól. Dodaj chronioną metodę setHealth(int health), która pilnuje, aby wartość health mieściła się w zakresie od 0 do maxHealth. Utwórz metodę takeDamage(int damage), która zmniejsza wartość health i zwraca "[name] takes [damage] damage! Health: [health]/[maxHealth]". Dodaj metodę isAlive(), która zwraca true, jeśli wartość health jest większa od 0. Zadeklaruj metodę abstrakcyjną getCharacterClass(), która zwraca String.
  • Warrior.java: Utwórz klasę rozszerzającą Character i implementującą Attackable. Dodaj prywatne pole strength (int). Konstruktor przyjmuje name, maxHealth, level i strength. Zaimplementuj getCharacterClass(), aby zwracała "Warrior". Zaimplementuj getDamageType(), aby zwracała PHYSICAL. Zaimplementuj attack(Character target), aby zadawała obrażenia równe sumie strength i level, wywoływała metodę takeDamage celu i zwracała "[name] strikes with [damageType description] for [damage] damage!", a następnie znak nowej linii i wynik wywołania takeDamage.
  • Mage.java: Utwórz klasę rozszerzającą Character i implementującą zarówno Attackable, jak i Healable. Dodaj prywatne pola intelligence (int) i mana (int). Konstruktor przyjmuje name, maxHealth, level, intelligence i mana. Zaimplementuj getCharacterClass(), aby zwracała "Mage". Zaimplementuj getDamageType(), aby zwracała MAGICAL. Zaimplementuj attack(Character target), aby zadawała obrażenia równe intelligence pomnożonemu przez 2, w tym samym formacie co w klasie Warrior. Zaimplementuj heal(int amount), aby przywracała zdrowie (używając setHealth) i zwracała "[name] channels healing magic! Health: [health]/[maxHealth]".
  • Main.java: Ożyw swój system gry! Otrzymasz ciąg poleceń rozdzielonych przecinkami:
    • CREATE_WARRIOR:name:maxHealth:level:strength
    • CREATE_MAGE:name:maxHealth:level:intelligence:mana
    • ATTACK:attackerName:targetName
    • HEAL:mageName:amount
    • STATUS:characterName

    Przechowuj kolekcję postaci. Przetwarzaj każde polecenie i wyświetlaj:

    • CREATE_WARRIOR/CREATE_MAGE: [name] the [characterClass] joins the battle!
    • ATTACK: Wyświetl wynik ataku (String zwrócony przez metodę attack)
    • HEAL: Wyświetl wynik leczenia lub [name] cannot heal, jeśli postać nie jest Magiem
    • STATUS: [name] ([characterClass]) - Level [level] - Health: [health]/[maxHealth] - [Alive/Defeated]

    Po wykonaniu wszystkich poleceń wyświetl --- Battle Summary ---, a następnie status każdej postaci.

Otrzymasz jedno wejście: ciąg poleceń rozdzielonych przecinkami.

Na przykład dla wejścia CREATE_WARRIOR:Thorin:100:5:15,CREATE_MAGE:Gandalf:80:7:12:50,ATTACK:Thorin:Gandalf,HEAL:Gandalf:25,STATUS:Gandalf wynikiem będzie:

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

To wyzwanie łączy dziedziczenie (hierarchię Character), implementację wielu interfejsów (Mage implementuje zarówno Attackable, jak i Healable), typy wyliczeniowe z metodami (DamageType), polimorfizm (jednolite traktowanie różnych typów postaci) oraz enkapsulację (chronione zarządzanie zdrowiem) w angażującym systemie gry!

Spróbuj swoich sił

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: Użyj kolekcji do przechowywania postaci (LinkedHashMap zachowuje kolejność dodawania)
        // LinkedHashMap<String, Character> characters = new LinkedHashMap<>();
        
        // TODO: Podziel input według przecinków, aby uzyskać poszczególne polecenia
        // String[] commands = input.split(",");
        
        // TODO: Przetwórz każde polecenie:
        // - CREATE_WARRIOR:name:maxHealth:level:strength
        //   Wypisz: "[name] the Warrior joins the battle!"
        // 
        // - CREATE_MAGE:name:maxHealth:level:intelligence:mana
        //   Wypisz: "[name] the Mage joins the battle!"
        // 
        // - ATTACK:attackerName:targetName
        //   Wypisz wynik ataku zwrócony przez metodę attack
        // 
        // - HEAL:mageName:amount
        //   Wypisz wynik leczenia lub "[name] cannot heal", jeśli postać nie jest typu Mage
        // 
        // - STATUS:characterName
        //   Wypisz: "[name] ([characterClass]) - Level [level] - Health: [health]/[maxHealth] - [Alive/Defeated]"
        
        // TODO: Po wykonaniu wszystkich poleceń wypisz "--- Battle Summary ---"
        // Następnie wypisz stan każdej postaci
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Java online