Come posso rappresentare le stanze, le azioni e l'inventario associati in un gioco di avventura basato su testo?


8

Sto appena iniziando a imparare a creare giochi. Ho creato un semplice gioco basato sul testo in cui l'utente può passeggiare tra le stanze e interagire con gli oggetti in ogni stanza. Tuttavia, sento che il mio approccio ha portato a un mucchio di cattivi codici di spaghetti. Non sono sicuro di quale sarebbe un buon modo per strutturare un gioco come questo.

Il mio approccio era di avere una classe con un metodo per ogni stanza e tutti gli oggetti e le interazioni che si potevano fare in quella stanza. Ad esempio, questo è il metodo per lo studio:

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 ();
            }
        }
    }
}

Non mi sembra che questo sia un approccio che scalerà; cioè, non posso davvero scrivere funzioni come questa per ogni stanza. Credo che usare i file in qualche modo sarebbe una buona strategia per evitare la "codifica" che sto attualmente facendo. Ma non sono sicuro di come ci riesco?


Questo è davvero un argomento di programmazione generale, tranne forse i bit relativi ai loop di gioco e simili (che è molto ampio). È difficile da dire, però, perché la tua domanda non è chiara come scritta.

non capisco come non sia chiaro come ho fatto del mio meglio per spiegare. forse potresti aiutarmi?
Mohamed Serry,

Gran parte di ciò è dovuto alla mancanza di punteggiatura, maiuscole e spaziatura tra i paragrafi. Fondamentalmente sembra che tu stia chiedendo come evitare di dover codificare una singola classe per stanza nel tuo gioco. È corretto? In tal caso, posso aiutarti a modificare la tua domanda.

in una certa misura sì. Voglio evitare la codifica definitiva di tutto il gioco in pratica.
Mohamed Serry,

Risposte:


10

Sei sulla strada giusta con la tua idea di utilizzare i file per alleviare la quantità di comportamento codificato che hai. Vuoi rendere i tuoi dati di gioco guidati il più possibile: non è un concetto complicato, è esattamente quello che sembra. Guidare il comportamento del gioco tramite dati anziché direttamente tramite codice.

Una buona mentalità da prendere quando si determina come guidare un sistema tramite i dati è cercare le generalità. Quali sono le cose in comune tra tutte le istanze di questi sistemi? I punti in comune diventano proprietà del sistema e i valori di tali proprietà sono i dati. Le stanze, ad esempio, di solito hanno tutte una descrizione e un elenco di uscite. Possono anche avere un "inventario", un elenco di oggetti presenti nella stanza.

Un'opzione che puoi perseguire è quella di utilizzare file di testo semplice o XML (entrambi i quali sono abbastanza semplici da analizzare in C #) per archiviare dati e contenuti della room.

Considera un file strutturato XML come questo:

<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>

Questa semplice struttura definisce esattamente ciò che ho elencato sopra. Una Roomclasse cooresponding avrebbe proprietà per Description, a List<T>di uscite (che sono riferimenti ad altre stanze e il comando "go" usato per arrivarci, nell'esempio sopra che porta a nord porterebbe il giocatore in corridoio). C'è anche una List<T>delle voci.

Invece di mettere un whileciclo in una funzione per ogni stanza (cosa che non puoi fare ora poiché hai Roomcomunque una sola classe), fai un ciclo principale più generalizzato:

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;
    ...
  }
}

Nota che la Command.Parsefunzione viene lasciata come un excersize per te, ma sostanzialmente dovrebbe analizzare l'input dell'utente e restituire una sorta di coppia "verbo / oggetto" o simile (vedi questa domanda per un kickstart nel farlo, è un po 'oltre lo scopo del tuo domanda). Nell'esempio sopra, il verbo sarebbe "go" e l'oggetto potrebbe essere "nord" o "sud" o qualsiasi altra cosa.

Ma oltre a ciò, ciò che questo loop sta facendo è presentare le stanze in modo generalizzato; ogni volta che stampi la descrizione della stanza, attendi l'input dell'utente. Se l'input dell'utente è "vai in un'altra stanza", trovi che l'uscita della stanza attuale corrisponde alla direzione immessa dall'utente. Se non vi è alcuna uscita in quella direzione, ditelo, altrimenti impostate la stanza corrente su quella nuova stanza. Quindi ripeti.

Puoi continuare a perfezionare questo approccio (ad esempio, quanto sopra stampa la descrizione della stanza dopo ogni comando; puoi vedere come farlo stampare la descrizione solo la prima volta che entri nella stanza? Che ne dici di quel plus quando scrivi un "look" "comando?). Puoi anche ridimensionarlo per includere la gestione degli articoli in modo simile.


Grazie per il tuo supporto, Josh. proverò questo e proverò a sviluppare i progressi il più possibile
Mohamed Serry,

1

Se conosci html, puoi pensare alle stanze come pagine web, le uscite come collegamenti, le azioni forse come ancore e il gioco stesso come un browser. L'unica cosa aggiuntiva che il gioco deve gestire è un inventario e gli NPC, che sono fondamentalmente una o due classi statiche con lo stato di ogni oggetto e personaggio nel gioco, sono stati presi, sono già stati usati / parlati, ce l'hanno stato distrutto / sconfitto.

Se usi HTML invece di XML puro in un modo simile a quello descritto da Josh, potresti eseguire il debug nel browser, almeno per quanto riguarda la navigazione.


la risposta di josh è tecnicamente più approfondita e direttamente pertinente, ma questa analogia è piuttosto buona e può aiutare a capire il concetto generale
jhocking
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.