Как я могу представить комнаты и связанные действия и инвентарь в текстовой приключенческой игре?


8

Я только начинаю учиться делать игры. Я создал простую текстовую игру, в которой пользователь может ходить между комнатами и взаимодействовать с объектами в каждой комнате. Тем не менее, я чувствую, что мой подход привел к куче плохого кода спагетти. Я не уверен, каким будет хороший способ структурировать такую ​​игру.

Мой подход состоял в том, чтобы иметь один класс с методом для каждой комнаты и всех объектов и взаимодействий, которые можно было бы выполнить в этой комнате. Например, это метод исследования:

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

Я не чувствую, что это подход, который будет масштабироваться; то есть я не могу написать такие функции для каждой комнаты. Я считаю, что использование файлов каким-либо образом было бы хорошей стратегией, чтобы избежать «жесткого кодирования», которое я сейчас делаю. Но я не уверен, как мне этого добиться?


Это действительно более общая тема программирования, за исключением, может быть, битов о игровых циклах и тому подобном (которые очень широки). Трудно сказать, хотя, потому что ваш вопрос очень неясен, как написано.

Я не понимаю, как это не ясно, так как я старался изо всех сил, чтобы объяснить. возможно, вы могли бы помочь мне?
Мохамед Серри

Во многом это связано с отсутствием пунктуации, заглавных букв и пробелов между абзацами. По сути, это звучит так, как будто вы спрашиваете, как избежать жесткого кодирования одного класса для комнаты в вашей игре. Это верно? Если это так, я могу помочь отредактировать ваш вопрос.

в какой-то степени да. я хочу избежать жесткого кодирования всей игры в принципе.
Мохамед Серри

Ответы:


10

Вы идете по правильному пути с вашим представлением об использовании файлов, чтобы помочь уменьшить количество жестко запрограммированного поведения, которое вы имеете. Вы хотите, чтобы ваши игровые данные управлялись как можно больше: это не сложная концепция, это именно то, на что это похоже. Управляйте поведением игры через данные, а не напрямую через код.

Чтобы определить, как управлять какой-либо системой через данные, нужно подумать об общих чертах. Что общего между всеми экземплярами этих систем? Общности становятся свойствами системы, а значения этих свойств являются данными. Например, комнаты обычно имеют описание и список выходов. У них также может быть «инвентарь», список предметов, находящихся в комнате.

Одним из вариантов, который вы можете использовать, является использование простого текста или файлов XML (оба из которых довольно просты для анализа в C #) для хранения данных и содержимого комнаты.

Рассмотрим структурированный файл XML следующим образом:

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

Эта простая структура точно определяет то, что я перечислил выше. Соответствующий Roomкласс будет иметь свойства для выхода Descriptiona List<T>(которые являются ссылками на другие комнаты, и команда «go», используемая для этого, в приведенном выше примере движение на север приведет игрока в коридор). Там также List<T>из предметов.

Вместо того, чтобы помещать whileцикл в функцию для каждой комнаты (что вы не можете сделать сейчас, так как у вас все равно есть только один Roomкласс), вы делаете более обобщенный основной цикл:

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

Обратите внимание, что Command.Parseфункция оставлена ​​для вас в качестве примера, но в основном она должна анализировать пользовательский ввод и возвращать какую-то пару «глагол / объект» или что-то подобное (см. Этот вопрос для ознакомления с этим, это немного выходит за рамки вашего вопрос). В приведенном выше примере глаголом будет «идти», а объектом может быть «север» или «юг» или что-то еще.

Но помимо этого, то, что делает этот цикл, представляет комнаты в обобщенном виде; каждый раз, когда вы печатаете описание комнаты, ждите ввода пользователя. Если пользовательский ввод «перейти в какую-то другую комнату», вы обнаружите, что выход из текущей комнаты соответствует направлению, введенному пользователем. Если в этом направлении нет выхода, скажем так, в противном случае установите текущую комнату в эту новую комнату. Тогда повторите.

Вы можете продолжить совершенствовать этот подход (например, приведенный выше выводит описание комнаты после каждой команды; можете ли вы увидеть, как сделать так, чтобы оно печатало описание только при первом входе в комнату? Как насчет этого плюса при вводе «вида» «команда?). Вы также можете уменьшить его, чтобы включить обработку элементов аналогичным образом.


Спасибо большое за вашу поддержку, Джош. Я попытаюсь сделать это и постараюсь развить прогресс настолько, насколько смогу
Мохамед Серри

1

Если вы знаете html, вы можете думать о комнатах как о веб-страницах, о выходах как о ссылках, о действиях, возможно, как о якорях, так и о самой игре как о браузере. Единственной дополнительной вещью, которой должна управлять игра, является инвентарь и неигровые персонажи, которые в основном представляют собой один или два статических класса с состоянием каждого предмета и персонажа в игре, были ли они взяты, уже использовались / разговаривали с ними, не так ли? был уничтожен / побежден.

Если вы используете html вместо чистого xml аналогично тому, что описал Джош, вы можете отлаживать в браузере, по крайней мере, в том, что касается навигации.


Ответ Джоша более технически тщателен и имеет прямое отношение, но эта аналогия довольно хороша и может помочь понять общую концепцию
jhocking
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.