Menu
Coddy logo textTech

Spielfiguren-Komponente

Teil des Abschnitts Objektorientierte Programmierung der C#-Journey von Coddy — Lektion 69 von 70.

challenge icon

Aufgabe

Einfach

Lass uns ein Spielcharakter-System mit dem komponentenbasierten Architekturmuster erstellen! Anstatt starre Vererbungshierarchien zu schaffen, wirst du Charaktere zusammensetzen, indem du unabhängige Komponenten hinzufügst, die spezifische Verhaltensweisen steuern – ein flexibler Ansatz, der in der Spieleentwicklung weit verbreitet ist.

Du wirst deinen Code über fünf Dateien organisieren:

  • IComponent.cs: Definiere ein IComponent-Interface im Namespace Game.Components. Jede Komponente muss eine Update()-Methode haben, die ausgibt, was die Komponente gerade tut.
  • HealthComponent.cs: Erstelle eine HealthComponent-Klasse, die IComponent implementiert. Sie sollte die aktuellen und maximalen Lebenspunkte verfolgen, mit Methoden für TakeDamage(int amount) und Heal(int amount). Die Gesundheit sollte niemals unter 0 sinken oder das Maximum überschreiten. Füge ein event Action<int> HealthChanged hinzu, das ausgelöst wird, wann immer sich die Gesundheit ändert, und den neuen Gesundheitswert übergibt. Die Update()-Methode sollte den aktuellen Gesundheitsstatus ausgeben.
  • InventoryComponent.cs: Erstelle eine InventoryComponent-Klasse, die IComponent implementiert. Sie verwaltet eine Liste von Item-Namen mit den Methoden AddItem(string item) und RemoveItem(string item) (gibt einen bool zurück, der den Erfolg anzeigt). Die Update()-Methode sollte den Inhalt des Inventars ausgeben.
  • Character.cs: Erstelle eine Character-Klasse im Namespace Game, die eine Sammlung von Komponenten enthält. Dein Charakter benötigt eine Name-Eigenschaft und diese Methoden:
    • AddComponent(IComponent component) – fügt dem Charakter eine Komponente hinzu
    • GetComponent<T>() wobei T : IComponent – gibt die erste Komponente vom Typ T zurück, oder null, falls keine gefunden wurde
    • UpdateAll() – ruft Update() für jede hinzugefügte Komponente auf
  • Program.cs: Führe alles zusammen, indem du einen Charakter erstellst, Komponenten hinzufügst und Befehle verarbeitest.

Du wirst die folgenden Eingaben erhalten:

  • Name des Charakters
  • Anfängliche maximale Gesundheit für die HealthComponent
  • Anzahl der zu verarbeitenden Befehle
  • Für jeden Befehl: die Aktion gefolgt von den relevanten Daten

Befehlsformate:

damage
{amount}

heal
{amount}

add_item
{itemName}

remove_item
{itemName}

update

Ausgabeformate:

  • Wenn sich die Gesundheit ändert (über das Event): Health changed: {newHealth}
  • Beim Hinzufügen eines Items: Added: {itemName}
  • Beim Entfernen eines Items: Removed: {itemName} oder Item not found: {itemName}
  • Update() der HealthComponent: Health: {current}/{max}
  • Update() der InventoryComponent: Inventory: {item1}, {item2}, ... oder Inventory: empty

Wenn die Eingaben zum Beispiel wie folgt lauten:

Hero
100
7
add_item
Sword
add_item
Shield
damage
30
heal
10
remove_item
Potion
remove_item
Sword
update

Sollte die Ausgabe so aussehen:

Added: Sword
Added: Shield
Health changed: 70
Health changed: 80
Item not found: Potion
Removed: Sword
Health: 80/100
Inventory: Shield

Beachte, dass der Charakter nicht von etwas Speziellem erbt – er hält einfach Komponenten, die das Verhalten bereitstellen. Die Methode GetComponent<T>() verwendet Generics für einen typsicheren Abruf, und Events benachrichtigen, wenn sich die Gesundheit ändert. Dieser Kompositionsansatz ermöglicht es dir, Komponenten frei zu kombinieren!

Probier es selbst

using System;
using Game;
using Game.Components;

class Program
{
    public static void Main(string[] args)
    {
        // Charakternamen lesen
        string characterName = Console.ReadLine();
        
        // Anfängliche maximale Gesundheit lesen
        int maxHealth = Convert.ToInt32(Console.ReadLine());
        
        // Anzahl der Befehle lesen
        int numCommands = Convert.ToInt32(Console.ReadLine());
        
        // TODO: Erstelle einen Character mit dem angegebenen Namen
        
        // TODO: Erstelle HealthComponent mit maxHealth und InventoryComponent
        
        // TODO: Abonniere das HealthChanged-Event, um Folgendes auszugeben: Health changed: {newHealth}
        
        // TODO: Füge beide Komponenten zum Charakter hinzu
        
        // TODO: Verarbeite jeden Befehl
        for (int i = 0; i < numCommands; i++)
        {
            string command = Console.ReadLine();
            
            // TODO: Behandle jeden Befehlstyp:
            // - "damage": Menge lesen, TakeDamage auf der HealthComponent aufrufen
            // - "heal": Menge lesen, Heal auf der HealthComponent aufrufen
            // - "add_item": Item-Namen lesen, AddItem auf der InventoryComponent aufrufen
            // - "remove_item": Item-Namen lesen, RemoveItem auf der InventoryComponent aufrufen
            // - "update": UpdateAll auf dem Character aufrufen
        }
    }
}

Alle Lektionen in Objektorientierte Programmierung