В настоящее время я создаю собственную приключенческую игру. Теперь достаточно просто иметь один результат для каждого выбора и создавать линейный поток, но есть ли хороший алгоритм для того, чтобы все предыдущие выборы влияли на следующий результат? Я мог бы, очевидно, хранить каждый предыдущий выбор и иметь большие «IF» заявления, чтобы решить, но я подумал, есть ли лучший способ?
Часть меня задается вопросом, должен ли каждый вариант иметь «счет», и затем я использую его (возможно, с порогом), чтобы определить, каким должно быть следующее действие, и каждое действие добавляется к результату.
Я в основном делаю это в swift / SpriteKit, но я думаю, что это больше о концепции, чем код на данном этапе.
В ответ на комментарий Джоша ниже:
Я полагаю, что на данный момент я все еще нахожусь в концептуальной фазе, но каждая «страница» будет либо пользовательским объектом, либо файлом json. Я думал о вашем ответе (теперь удален) и, может быть, немного выбрал каждый вариант ENUM. Тогда каждая страница может иметь «оценку». Затем, используя предыдущие выбранные опции, определите, какие биты установлены, и это определяет, какую страницу. Я думаю, я просто подумал, было ли существующее решение этой проблемы, прежде чем я начал почти помогать решить, как мне отформатировать «историю»
Грубое предположение в формате:
{ "text":"You arrive in the dungeon and there are 2 doors",
"options":[
1: "Go left",
2: "Go Right"
],
"score" : 0 // first page
}
{"text" "You went left and meet a dragon",
"options":[
0: "Game over, you were eaten" // something to handle game over
],
"score" : 1
}
{"text" "You meet a mushroom who tells you the princess is in another castle",
"options":[
4: "Give up, game over", // something to handle game over
8: "Jump down the pipe"
],
"score" : 2
}
Спасибо
источник
if
символамиelse
«s»,switch
«s» иcase
«надеется», что вы закончите, прежде чем потеряете здравомыслие.Ответы:
Во многих Приключенческих / РПГ играх это делается двумя способами (может быть, я еще не знаю).
Использование флагов
Первый - установить флаг, если что-то произошло (обычно какая-то битовая маска). Это хорошо, если у вас мало вещей для отслеживания. В комнате / встрече может быть проверка против флага, который что-то меняет. В вашем примере можно добавить правило:
Где 2-й вариант появляется только если
flags & 64
установлен. Вы также можете реализовать этуsetflag
опцию, если появляется сцена или был сделан определенный выбор.Использование предметов
Второй вариант, это добавить предметы в инвентарь игрока. Это «этот предмет необходим для выполнения квеста», который вы часто видите в играх. Они в основном функционируют как переносные «флаги». Это может быть реализовано двумя способами (или комбинацией):
Предметом является «флаг»: попросите сцену или диалог проверить, есть ли у игрока определенный предмет в его инвентаре. Это очень похоже на механизм проверки флага, как описано выше. Положительным моментом является то, что вам может быть намного проще проектировать встречи, когда вы проверяете знакомые именованные объекты.
Элементы имеют свойства, которые работают как флаг. Например, в «Ведьмаке 3» игрок получает объект, способный рассеять иллюзорные стены. Сам этот элемент может быть «флагом», но также может быть и то, что у объекта есть свойство
can_dispel_illusions
. Преимущество в том, что вы можете реализовать несколько объектов, которые можно использовать в одном и том же сценарии. Таким образом, сцена / диалог / дверь может проверить, есть ли у игрока «что-то» в инвентаре, у которого есть свойствоcan_dispel_illusions
.Это дает вам возможность дать игроку иллюзию выбора; если игрок не встретил ведьму в первой сцене, пропустив, таким образом, «жезл рассеивания», то позже игрок может получить «кольцо рассеивания» от какого-то сомнительного торговца, что предотвратит состояние игры, в котором невозможно выиграть.
Если вы не планируете давать игроку «настоящий» инвентарь, квестовые предметы могут попасть в список, скрытый от игрока.
пример:
а также:
источник
Одно из решений, которое я видел, которое развивает ваш подход, состоит в том, чтобы иметь различные атрибуты с соответствующими оценками. Некоторые варианты приводят к изменению одного или нескольких из этих баллов. Очки в свою очередь могут изменить выбор, доступный игроку.
Например, в начале истории могут быть некоторые варианты боевых встреч. Если игрок вступит в бой, атрибут храбрости увеличится, а бегство уменьшит его. Позже, определенная ветка истории может быть доступна, только если показатель храбрости был выше или ниже заданного порога. Чтобы добавить больше глубины, некоторые решения должны затрагивать более одного балла. Например, сбор карманов может увеличить счет скрытности и снизить показатель честности.
Вообще, я видел, как этот подход использовался в симуляторах интерактивного жанра. Вы можете услышать, как Дэн Фабулич из Choice Of Games обсуждает это решение в этом эпизоде круглого стола Game Design.
Преимущества этого подхода:
Некоторые недостатки:
источник
Это большая проблема, с которой сталкиваются сюжетно-ориентированные игры: комбинаторный взрыв. Таким образом, если вы посмотрите, например, на игры Bioware или Telltale, то обнаружите, что наиболее распространенным подходом все еще остается попытка ограничить историю, чтобы она была более линейной, и не допускать, чтобы последствия действий ограничивались их главами.
Подход, который использует Bioware, похоже, разделяет каждую историю на отдельные темы или под-дуги. Дуги в значительной степени независимы друг от друга, но происходят одновременно и могут способствовать окончанию. Таким образом, вам не нужно моделировать каждую комбинацию дуг, вы просто чередуете главы между дугами, и последствия ограничиваются конкретной поддугой, с которой вы сейчас имеете дело, или тем, как закончить дугу. (или как закончить дугу персонажа. Если вам больше не нужен этот NPC, вам часто предоставляется выбор: убить его, арестовать или освободить, например, предоставив вам выбор, но ограничив последствия остальными. истории)
Тогда для окончания всей истории нужно знать, как закончилась каждая дуга, и связать весь рассказ аккуратным небольшим бантиком.
Как бы вы смоделировали это в программе?
Это просто отталкивает проблему на один уровень (потому что каждая поддуга должна отслеживать различия, как в простом рассказе), но в основном у вас будет массив флагов (например, битовое поле или список элементов с флагами, представляющими способность влиять на определенные результаты) для каждой под-дуги.
Кроме того, когда вы говорите о своем окончании, вы обычно используете тот же подход чередования, когда рассказываете игроку о последствиях: результат каждой поддуги получает свой собственный абзац / узел разговора, что значительно упрощает ваши условия.
источник
Это может занять некоторое время, но разработка собственного дерева (например, дерева поведения или дерева диалогов, но для страниц) может быть полезным. И вы можете использовать один из них в качестве модели. Что-то вроде этого:
Как работают диалоговые деревья?
Это позволит вам адаптировать его к вашим конкретным потребностям, но также позволит коду выполнять большую часть работы.
источник
Что делать, если вы использовали подход типа двигателя правила? Когда игрок взаимодействует с неигровым персонажем, игра запускает урезанный механизм правил, который запускается с флагами, которые были созданы в результате прошлых выборов / поведения, и проверяет его на соответствие заранее заданным вами правилам. Что-то вроде Drools , вероятно, слишком большое и амбициозное, не говоря уже о медленном, но механизм правил ограниченного объема теоретически может дать вам лучшую производительность и большую гибкость.
источник