Comment représenter les salles et les actions et inventaires associés dans un jeu d'aventure basé sur du texte?

8

Je commence tout juste à apprendre à créer des jeux. J'ai créé un jeu simple basé sur du texte où l'utilisateur peut se promener entre les pièces et interagir avec les objets de chaque pièce. Cependant, j'ai l'impression que mon approche a conduit à une pile de mauvais code de spaghetti. Je ne sais pas quelle serait une bonne façon de structurer un jeu comme celui-ci.

Mon approche était d'avoir une classe avec une méthode pour chaque pièce et tous les objets et interactions qui pouvaient être faits dans cette pièce. Par exemple, voici la méthode pour l'étude:

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

Je ne pense pas que ce soit une approche qui évoluera; c'est-à-dire que je ne peux pas vraiment écrire des fonctions comme celle-ci pour chaque pièce. Je crois que l'utilisation de fichiers d'une certaine manière serait une bonne stratégie pour éviter le "codage en dur" que je fais actuellement. Mais je ne sais pas comment je peux y arriver?

Mohamed Serry
la source
C'est vraiment plus un sujet de programmation général, sauf peut-être les bits sur les boucles de jeu et autres (qui sont très larges). C'est difficile à dire, cependant, car votre question n'est pas très claire telle qu'elle est écrite.
je ne comprends pas comment ce n'est pas clair car j'ai fait de mon mieux pour expliquer. peut-être pourriez-vous m'aider?
Mohamed Serry
Cela est dû en grande partie à l'absence de ponctuation, de majuscule et d'espacement entre les paragraphes. Fondamentalement, il semble que vous vous demandiez comment éviter d'avoir à coder en dur une seule classe par salle dans votre jeu. Est-ce exact? Si c'est le cas, je peux vous aider à modifier votre question.
dans une certaine mesure, oui. je veux éviter de coder en dur tout le jeu essentiellement.
Mohamed Serry

Réponses:

10

Vous êtes sur la bonne voie avec votre idée d'utiliser des fichiers pour réduire le nombre de comportements codés en dur que vous avez. Vous voulez que vos données de jeu soient pilotées autant que possible: ce n'est pas un concept compliqué, c'est exactement ce à quoi cela ressemble. Pilotez le comportement du jeu via les données plutôt que directement via le code.

Un bon état d'esprit à prendre pour déterminer comment piloter un système via des données est de rechercher les généralités. Quelles sont les choses en commun entre toutes les instances de ces systèmes? Les points communs deviennent des propriétés du système et les valeurs de ces propriétés sont les données. Les chambres, par exemple, ont généralement toutes une description et une liste de sorties. Ils peuvent également avoir un «inventaire», une liste d'articles qui se trouvent dans la salle.

Une option que vous pouvez poursuivre consiste à utiliser du texte brut ou des fichiers XML (qui sont assez simples à analyser en C #) pour stocker les données et le contenu de la salle.

Considérez un fichier structuré XML comme celui-ci:

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

Cette structure simple définit exactement ce que j'ai énuméré ci-dessus. Une cooresponding Roomclasse aurait des propriétés pour le Description, une List<T>des sorties (qui sont des références à d' autres chambres et la commande « go » utilisée pour y arriver, dans l'exemple ci - dessus vers le nord prendrait le joueur dans le couloir). Il y a aussi un List<T>des articles.

Plutôt que de mettre une whileboucle dans une fonction pour chaque pièce (ce que vous ne pouvez pas faire maintenant car vous n'avez de Roomtoute façon qu'une seule classe), vous faites une boucle principale plus généralisée:

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

Notez que la Command.Parsefonction est laissée comme une excersize pour vous, mais devrait fondamentalement analyser l'entrée utilisateur et retourner une sorte de paire "verbe / objet" ou similaire (voir cette question pour un coup de pouce pour le faire, c'est un peu au-delà de la portée de votre question). Dans l'exemple ci-dessus, le verbe serait "go" et l'objet pourrait être "north" ou "south" ou autre chose.

Mais au-delà, ce que fait cette boucle, c'est de présenter les salles de manière généralisée; à chaque fois, vous imprimez la description de la pièce, attendez la saisie de l'utilisateur. Si l'entrée utilisateur est "aller dans une autre pièce", la sortie de la pièce actuelle correspond à la direction entrée par l'utilisateur. S'il n'y a pas de sortie dans cette direction, dites-le, sinon réglez la pièce actuelle sur cette nouvelle pièce. Répétez ensuite.

Vous pouvez continuer à affiner cette approche (par exemple, ce qui précède imprime la description de la pièce après chaque commande; pouvez-vous voir comment la faire imprimer la description uniquement la première fois que vous entrez dans la pièce? Qu'en est-il plus lorsque vous tapez un "look" "commande?). Vous pouvez également le mettre à l'échelle pour inclure la gestion des articles de manière similaire.

Communauté
la source
Merci beaucoup pour votre soutien josh. je vais tenter cela et essayer de développer le plus de progrès possible
Mohamed Serry
1

Si vous connaissez le HTML, vous pouvez considérer les salles comme des pages Web, les sorties comme des liens, les actions peut-être comme des ancres et le jeu lui-même comme un navigateur. La seule chose supplémentaire que le jeu doit gérer est un inventaire et des PNJ, qui sont fondamentalement une classe statique ou deux avec l'état de chaque élément et personnage du jeu, a-t-il été pris, a-t-il déjà été utilisé / discuté, l'a-t-il été détruit / vaincu.

Si vous utilisez html au lieu de xml pur d'une manière similaire à ce que Josh a décrit, vous pouvez déboguer dans le navigateur, au moins en ce qui concerne la navigation.

AturSams
la source
La réponse de Josh est plus approfondie techniquement et directement pertinente, mais cette analogie est assez bonne et peut aider à comprendre le concept global
jhocking