Wie kann ich Räume und zugehörige Aktionen und Inventar in einem textbasierten Abenteuerspiel darstellen?

8

Ich fange gerade erst an zu lernen, Spiele zu machen. Ich habe ein einfaches textbasiertes Spiel erstellt, in dem der Benutzer zwischen Räumen herumlaufen und mit den Objekten in jedem Raum interagieren kann. Ich habe jedoch das Gefühl, dass mein Ansatz zu einem Haufen schlechten Spaghetti-Codes geführt hat. Ich bin mir nicht sicher, wie man ein solches Spiel gut strukturieren kann.

Mein Ansatz war es, eine Klasse mit einer Methode für jeden Raum und alle Objekte und Interaktionen zu haben, die in diesem Raum durchgeführt werden konnten. Dies ist beispielsweise die Methode für die Studie:

public static void Study() 
{
    bool studyexited = false;

    while (!studyexited) {
        string usercommand = Console.ReadLine ();
        usercommand.ToLower ();

        switch (usercommand) {
        case "turn left":
            GameEventText.StudyLeft ();
            break;
        case "turn right":
            GameEventText.StudyRight ();
            break;
        case "go forward":
            Notes firstsetofclues = new Notes ("First Note");
            GameEventText.StudyFront ();
            string firststudycommand = Console.ReadLine ();
            firststudycommand.ToLower ();

            if (firststudycommand == "read note") {
                firstsetofclues.Firstnotereading ();
            }

            Console.WriteLine ("Picking up this note would prove valuable");
            string secondstudycommand = Console.ReadLine ();
            secondstudycommand.ToLower ();

            if (secondstudycommand == "pick up note") {
                if (MainClass.PlayerInventory.AddItem (firstsetofclues)) 
                {
                    Console.WriteLine ("The note has been added to your inventory");
                } else {
                    Console.WriteLine ("Your inventory is full");
                }

                MainClass.PlayerInventory.Inventorydisplay ();
            }
        }
    }
}

Ich glaube nicht, dass dies ein skalierbarer Ansatz ist. Das heißt, ich kann solche Funktionen nicht für jeden Raum schreiben . Ich glaube, dass die Verwendung von Dateien in irgendeiner Weise eine gute Strategie wäre, um die "harte Codierung" zu vermeiden, die ich derzeit mache. Aber ich bin mir nicht sicher, wie ich das erreichen kann?

Mohamed Serry
quelle
Dies ist wirklich eher ein allgemeines Programmierthema, außer vielleicht die Teile über Spieleschleifen und dergleichen (die sehr weit gefasst sind). Es ist jedoch schwer zu sagen, da Ihre Frage wie geschrieben sehr unklar ist.
Ich verstehe nicht, wie es nicht klar ist, als ich mein Bestes gab, um es zu erklären. Vielleicht könntest du mir helfen?
Mohamed Serry
Vieles hat mit dem Mangel an Interpunktion, Groß- und Kleinschreibung und Abstand zwischen Absätzen zu tun. Grundsätzlich klingt es so, als würden Sie sich fragen, wie Sie vermeiden können, eine einzelne Klasse pro Raum in Ihrem Spiel hart zu codieren. Ist das korrekt? Wenn ja, kann ich Ihnen bei der Bearbeitung Ihrer Frage helfen.
bis zu einem gewissen Grad ja. Ich möchte im Grunde vermeiden, das ganze Spiel hart zu codieren.
Mohamed Serry

Antworten:

10

Sie sind auf dem richtigen Weg mit Ihrer Vorstellung, Dateien zu verwenden, um das Ausmaß Ihres hartcodierten Verhaltens zu verringern. Sie möchten Ihre Spieldaten so weit wie möglich steuern: Es ist kein kompliziertes Konzept, es ist genau das, wonach es sich anhört. Steigern Sie das Spielverhalten über Daten und nicht direkt über Code.

Eine gute Einstellung bei der Bestimmung, wie ein System über Daten gesteuert werden soll, ist die Suche nach allgemeinen Informationen. Welche Gemeinsamkeiten haben alle Instanzen dieser Systeme? Die Gemeinsamkeiten werden zu Eigenschaften des Systems, und die Werte dieser Eigenschaften sind die Daten. Zimmer zum Beispiel haben normalerweise alle eine Beschreibung und eine Liste von Ausgängen. Sie können auch ein "Inventar" haben, eine Liste von Gegenständen, die sich im Raum befinden.

Eine Option, die Sie verfolgen können, ist die Verwendung von Nur-Text- oder XML-Dateien (beide sind in C # recht einfach zu analysieren), um Raumdaten und -inhalte zu speichern.

Stellen Sie sich eine XML-strukturierte Datei wie folgt vor:

<room name="Study">
  <description>
  You enter a well-furnished study. A heavy wooden desk sits in one corner, an ugly lamp illuminating its surface.
  </description>
  <exits>
    <exit command="north">Hallway</exit>
  </exits>
  <items>
    <item name="Pen">
  </items>
</room>

Diese einfache Struktur definiert genau das, was ich oben aufgeführt habe. Eine cooresponding RoomKlasse hätte Eigenschaften für die Descriptioneine List<T>der Ausgänge (die Verweise auf andere Räume und den „go“ Befehl verwendet , um dorthin zu gelangen, in dem obigen Beispiel in Richtung Norden würde den Spieler auf den Gang nehmen). Es gibt auch eine List<T>Reihe von Gegenständen.

Anstatt eine whileSchleife in eine Funktion für jeden Raum einzufügen (was Sie jetzt nicht tun können, da Sie Roomsowieso nur eine einzige Klasse haben), erstellen Sie eine allgemeinere Hauptschleife:

while(!done) {
  Console.WriteLine(currentRoom.Description);
  var command = Command.Parse(Console.ReadLine());
  switch(command.Verb) {
    case "go":
      nextRoom = allRooms[currentRoom.GetExitForDirection(command.Object)];
      if (nextRoom == null) {
        Console.WriteLine("You cannot go that way.");
      }
      else {
        currentRoom = nextRoom;
      }
      break;
    ...
  }
}

Beachten Sie, dass die Command.ParseFunktion als Übungsgröße für Sie übrig bleibt, aber im Grunde genommen Benutzereingaben analysieren und eine Art "Verb / Objekt" -Paar oder ähnliches zurückgeben sollte (siehe diese Frage für einen Kickstart, dies geht etwas über Ihren Rahmen hinaus Frage). Im obigen Beispiel wäre das Verb "go" und das Objekt könnte "north" oder "south" oder was auch immer sein.

Darüber hinaus präsentiert diese Schleife die Räume verallgemeinert. Jedes Mal, wenn Sie fertig sind, drucken Sie die Raumbeschreibung aus und warten auf Benutzereingaben. Wenn die Benutzereingabe "In einen anderen Raum gehen" lautet, finden Sie den Ausgang des aktuellen Raums entsprechend der vom Benutzer eingegebenen Richtung. Wenn es in dieser Richtung keinen Ausgang gibt, sagen Sie dies, andernfalls stellen Sie den aktuellen Raum auf diesen neuen Raum ein. Dann wiederholen.

Sie können diesen Ansatz weiter verfeinern (z. B. druckt das Obige die Raumbeschreibung nach jedem Befehl aus; können Sie sehen, wie die Beschreibung nur beim ersten Betreten des Raums gedruckt wird? Wie wäre es damit, wenn Sie einen "Look" eingeben? " Befehl?). Sie können es auch skalieren, um die Handhabung von Elementen auf ähnliche Weise einzuschließen.

Gemeinschaft
quelle
Vielen Dank für Ihre Unterstützung Josh. Ich werde dies versuchen und versuchen, Fortschritte so weit wie möglich zu entwickeln
Mohamed Serry
1

Wenn Sie HTML kennen, können Sie sich die Räume als Webseiten vorstellen, die Ausgänge als Links, die Aktionen vielleicht als Anker und das Spiel selbst als Browser. Das einzige zusätzliche, was das Spiel verwalten muss, ist ein Inventar und NPCs, die im Grunde genommen eine oder zwei statische Klassen mit dem Status jedes Gegenstands und Charakters im Spiel sind. Wurde es genommen, wurde es bereits benutzt / angesprochen, oder? wurde zerstört / besiegt.

Wenn Sie HTML anstelle von reinem XML auf ähnliche Weise wie von Josh beschrieben verwenden, können Sie im Browser debuggen, zumindest was die Navigation betrifft.

AturSams
quelle
Joshs Antwort ist technisch gründlicher und direkt relevanter, aber diese Analogie ist ziemlich gut und kann helfen, das Gesamtkonzept zu verstehen
jhocking