Komponent postaci w grze
Część sekcji Programowanie obiektowe ścieżki C# w Coddy. Lekcja 69 z 70.
Wyzwanie
ŁatwyStwórzmy system postaci w grze, korzystając ze wzorca architektury opartej na komponentach! Zamiast tworzyć sztywne hierarchie dziedziczenia, będziesz składać postacie, dołączając niezależne komponenty obsługujące określone zachowania — to elastyczne podejście jest powszechnie stosowane w tworzeniu gier.
Rozmieścisz kod w pięciu plikach:
IComponent.cs: Zdefiniuj interfejsIComponentw przestrzeni nazwGame.Components. Każdy komponent musi mieć metodęUpdate(), która wyświetla, co robi dany komponent.HealthComponent.cs: Utwórz klasęHealthComponent, która implementujeIComponent. Powinna śledzić aktualną i maksymalną liczbę punktów zdrowia oraz udostępniać metodyTakeDamage(int amount)iHeal(int amount). Zdrowie nigdy nie powinno spaść poniżej 0 ani przekroczyć wartości maksymalnej. Dodaj zdarzenieevent Action<int> HealthChanged, które jest wywoływane za każdym razem, gdy zmienia się poziom zdrowia, i przekazuje jego nową wartość. MetodaUpdate()powinna wyświetlać aktualny stan zdrowia.InventoryComponent.cs: Utwórz klasęInventoryComponent, która implementujeIComponent. Zarządza ona listą nazw przedmiotów i udostępnia metodyAddItem(string item)orazRemoveItem(string item)(zwracaboolwskazujący, czy operacja się powiodła). MetodaUpdate()powinna wyświetlać zawartość ekwipunku.Character.cs: Utwórz klasęCharacterw przestrzeni nazwGame, która przechowuje kolekcję komponentów. Twoja postać powinna mieć właściwośćNameoraz następujące metody:AddComponent(IComponent component)— dołącza komponent do postaciGetComponent<T>()where T : IComponent — zwraca pierwszy komponent typu T albo null, jeśli nie znaleziono takiego komponentuUpdateAll()— wywołujeUpdate()dla każdego dołączonego komponentu
Program.cs: Połącz wszystko w całość, tworząc postać, dołączając komponenty i przetwarzając polecenia.
Otrzymasz następujące dane wejściowe:
- Nazwa postaci
- Początkowa maksymalna liczba punktów zdrowia dla HealthComponent
- Liczba poleceń do przetworzenia
- Dla każdego polecenia: akcja, a następnie odpowiednie dane
Formaty poleceń:
damage
{amount}
heal
{amount}
add_item
{itemName}
remove_item
{itemName}
updateFormaty danych wyjściowych:
- Gdy zmienia się poziom zdrowia (za pośrednictwem zdarzenia):
Health changed: {newHealth} - Podczas dodawania przedmiotu:
Added: {itemName} - Podczas usuwania przedmiotu:
Removed: {itemName}lubItem not found: {itemName} - Metoda
Update()klasy HealthComponent:Health: {current}/{max} - Metoda
Update()klasy InventoryComponent:Inventory: {item1}, {item2}, ...lubInventory: empty
Na przykład, jeśli dane wejściowe to:
Hero
100
7
add_item
Sword
add_item
Shield
damage
30
heal
10
remove_item
Potion
remove_item
Sword
updateDane wyjściowe powinny być następujące:
Added: Sword
Added: Shield
Health changed: 70
Health changed: 80
Item not found: Potion
Removed: Sword
Health: 80/100
Inventory: ShieldZauważ, że postać nie dziedziczy po żadnej specjalnej klasie — po prostu przechowuje komponenty, które zapewniają jej zachowania. Metoda GetComponent<T>() używa typów generycznych, aby pobieranie komponentów było bezpieczne pod względem typów, a zdarzenia informują o zmianie poziomu zdrowia. To podejście oparte na kompozycji pozwala swobodnie łączyć różne komponenty!
Spróbuj swoich sił
using System;
using Game;
using Game.Components;
class Program
{
public static void Main(string[] args)
{
// Wczytaj imię postaci
string characterName = Console.ReadLine();
// Wczytaj początkową maksymalną wartość zdrowia
int maxHealth = Convert.ToInt32(Console.ReadLine());
// Wczytaj liczbę poleceń
int numCommands = Convert.ToInt32(Console.ReadLine());
// TODO: Utwórz Character o podanym imieniu
// TODO: Utwórz HealthComponent z maxHealth oraz InventoryComponent
// TODO: Zasubskrybuj zdarzenie HealthChanged, aby wyświetlać: Health changed: {newHealth}
// TODO: Dodaj oba komponenty do postaci
// TODO: Przetwórz każde polecenie
for (int i = 0; i < numCommands; i++)
{
string command = Console.ReadLine();
// TODO: Obsłuż każdy typ polecenia:
// - "damage": wczytaj wartość, wywołaj TakeDamage na komponencie zdrowia
// - "heal": wczytaj wartość, wywołaj Heal na komponencie zdrowia
// - "add_item": wczytaj nazwę przedmiotu, wywołaj AddItem na komponencie ekwipunku
// - "remove_item": odczytaj nazwę przedmiotu, wywołaj RemoveItem na komponencie ekwipunku
// - "update": wywołaj UpdateAll na postaci
}
}
}
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrznePrzestrzenie nazw i dyrektywyWprowadzenie do klas i obiektówSłowo kluczowe „this”Metody i parametryPola a właściwościKonstruktoryInicjalizatory obiektówPodsumowanie — prosty kalkulator4Dziedziczenie
Podstawowa składnia dziedziczenia (:)Słowo kluczowe 'base'Słowa kluczowe virtual i overrideKlasy sealedBazowa klasa 'object'Powtórzenie – hierarchia pracowników7Zaawansowane funkcje
Przeciążanie operatorówIndeksery (this[])Nadpisywanie ToString()Metody rozszerzającePodsumowanie – własna lista2Właściwości i składowe statyczne
Właściwości automatyczneWłaściwości tylko do odczytu i zapisuPola i metody statyczneKlasy statyczneSkładowe z ciałem wyrażeniowym5Polimorfizm i interfejsy
Polimorfizm czasu kompilacji a czasu wykonaniaInterfejs a klasa abstrakcyjnaWiele interfejsówJawne implementowanie interfejsówRzutowanie w górę i w dółPowtórka — kalkulator kształtów8Zaawansowane koncepcje OOP
Kompozycja zamiast dziedziczeniaTypy generyczne (klasy i metody)Delegaty i zdarzeniaAtrybuty i refleksjaIDisposable i instrukcja usingPodstawy wstrzykiwania zależności11Wzorce projektowe, część 2
Wzorzec poleceniaWzorzec adapteraWzorzec dekoratoraWzorzec metody szablonowejWzorzec stanuWzorzec kompozytu3Architektura klas
Dane instancji a dane statyczneSłowa kluczowe 'readonly' i 'const'Pola zapasowePowtórzenie — menedżer kont bankowych6Hermetyzacja
Modyfikatory dostępuWłaściwości w hermetyzacjiImplementacja ukrywania danychWzorce niezmiennościPowtórka — dane studentów9Argumenty zmiennej liczby
Słowo kluczowe „params”Parametry opcjonalneArgumenty nazwanePrzeciążanie metodPoćwicz samodzielnie: Kompilator C# online