Готовый перевод How to make an Adventure Game / Как создать игру-квест: Текст веб-страницы

Эта статья будет касаться того, что происходит в программировании приключения.Идеи в большинстве случаев будет реализация агностиком, но где код предоставляется или реализации специфики обсуждаются они используют двигатель проект из моей книги программирования C # игры в качестве базы. Весь код можно ознакомиться в Интернете по лицензии MIT. Идеи покрыты здесь широко применяются, навигации сетки очень похож на описанный используются в таких играх, как ворота Baulder, в Planescape Torment и т.д., и с очень небольшой настройки таких сеток навигации может быть использована для 3D-игр, инвентаризация и диалога системы также распространены в играх с элементами РПГ.

Что такое квесты?

Квесты были популярным жанром в начале девяностых и недавно начали потихоньку возвращаться. Наиболее известный квест, возможно, серия Остров обезьян, где вы играете за чистолюбивого пирата.

Пользовательский интерфейс квестов может меняться от игры к игра, но картинка выше показывает интерфейс “Острова обезьян”. Игрок представлен на хорошей сцене, а игровой персонаэ обычно видим где-нибудь на экране. По умолчанию, если игрок кликает по экрану, то игровой персонаж будет пытаться дойти к точке клика.

а верхней картинке вы можете подвигать курсов водль замка на клетке темницы. Эта предмет в мире, с которым можно взаимодействовать. Игровой персонаж имеет несколько путей взаимодействия с вещами и на Острове Обезьян они перечислены на нижнем экране.

Нажимте “Посмотреть на”, нажмите “Открыть” и Гайбрашь, ваш игровой персонаж, тихо скажет о его впечатлении об этом замке (никто из других героев в игре не спрашивает кто Гайбраш разговаривает тоже, что ж, я предполагаю, что они думают, что он сумашедший :D).

Следующее в коммандах – это инвентарь, который показывает что Гайбраш в данный момент несет, Гайбрашь может взаимодействовать с этими предметами также как и с предметами на игровой сцене.

Сейчас вы возможно получили базовое представлен о пользовательском интерфейсе и взаимодействии игрока с миром. Это не очень сложно. Квесты определяются не только интерфейсами. Они в основном имеют сильную историю, в процессе развития событий игрок должен преодолевать различные проблемы и решать хитрые головоломки. Большинство квестов также позволяют игроку общаться с другими персонажами в игре, используя систему диалогов. Эти персонажи так же известны, как NPC (не игровые персонажи, non playing characters).

Как квест может быть разбит на подсистемы?

Квесты уже давно устоявшийся жанр, а это значит, что игру очень просто разбить на подсистемы, которые должны быть запрограммированы.

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

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

Наиболее сложная часть программы – система навигации и статья будет сфокусирована на этом.

Навигация

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

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

Навигация в играх в целом ссылается на поиск пути. Если вы хотите поискать больше информации, чем есть в этой статье, то это подходящее ключевое слово. Пути представляют собой линию, которой игровой персонаж должен следрвать для достижения желаемой позиции без прохождений сквозь стены, столы, маленьких собак и т.д. Путь ищется между точками текущего нахождения персонажа и позицией, где только что произошел шелчек мышью. Лучше всего если построенный путь является кратчайшим или наиболее точно приближается к кратчайшему пути – вы не захотите чтобы игровой персонаж блуждал по всему экрану, когда вы просите его пройти пять метров влево.

Алгоритмы поиска пути работают на графах, которые описывают пространство где игрок может перемещаться. Граф – это термин их области теории алгоритмов (не переживайте, объяснение очень простое), которое строится из набора вершин и связей между ними.

Выше приведенный граф показывает только путь между “Дороги из вне” в магазин через “Дверь магазина” узел. Это предотвращает сумащедшее блуждание персонажа повсюду. Вы можете заметить несколько вещей об этой системе:

- Не кажется, что у персонажа много свободы, что если он хочет остановится в середине магазина? Граф не позволит ему сделать это.

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

- Как же граф строится?

Мы сделаем его из навмеша, которым мы рассмотрим в кратце.

Поиск кратчайшего пути в графе

Наиболее общий путь нахождения кратчайшего пути в графе это использовать алгоритм A* (A звезда). Это метод который производит поиск по гарфу в попытке найти кратчайщий путь к выделенному целевому узлу. Этот алгоритм широко испольузется при программировании игр. Лучший ресурс по A* это страница A* Амита. По-сути, я думаю, он проделал отличную работу объясняя этот метод, и я не собираюсь даже пытаться сделать лучше. Почитайте эту страницу! :D

Это версия A* на моем репозитории в google code. Она очень базовая и простая, но она находит кратчайший путь для квестов. Это ссылка на реализацию. ( Сейчас программа рухнет, если путь между двумя узлами не может быть найден – я устраню это в будущем :D)

A* начитает со стартового узла и затем рассматривает всех его соседий, это дает некоторую значение “желаемости” для сосейдей и алгоритм применяется рекурсивно для большинства желаемых соседей. Желаемость обысно является функцией, которая вычислет расстояние до цели и предоставляет оценку желаемости для всех узлов на текущем пути. Алгоритм останавливается когда находит целевой узел или не может найти его. Это быстрое объеянение, для лучшего понимания зайдите на сайт Амита.

С A* в нашем кармане сейчас мы можем находить кратчайшие пути на грфе, но до сих пор мы еще нуждаемся в графе для поиска.

Использование Navmesh

НавМеш, как вы уже могли предполдожить, это сокражение от навигационный меш и, если по-простому, это всего лишь коллекция полиготов, которые описывают место, по которому игрок может перемещаться. Этот меш будет нариосван в баэкграунде рисунка с использование спецаильно разработанного инструмента.

На верхней картинке синие полигоны представляют собой пространство, по которому игрок может передвигаться. Розовые точки – это связи между полигонами, они показывают где игром может переходить с одного полигона на следующий. Граф будет создан из тестовых розовый связующих точек и центров всех полигонов. Стартоваи и конечные точки графа могут быть установлены где угодно внутри синего полигона.

Пусть сториться с позиции игрока и в точку клика мышки. Это значит, что заданначя точка (x, y) навигационного меша должна уметь определять в каком полигоне она находится.

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

Мне кажется что проще представить себе разницу, вогнутые , когда одна из вершин находится внутри полигона. В Китае и Японии канжи используются для представления идеи – посмотрите на две следующих канжи;
Предположите которая из выпуклая и которая вогнутая – круто, да?

Здесь представлен листинг, определяющий, если полигон в конкейве. В данном случае полигон лишь (List _vertices) с набором точек.

Следующая листинг нужен нам для проверки на пересечения.

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

Последнишак взять начальные и конечные точки, центры полигонов и соеденить узловые точки и построить граф, который сможет обеспечить работу алгоритма A*.

Путь будет возвращен, как список точек и персонаж сможет перемещаться вдоль этого листа.

Получить позицию персонажа -> pc_position

Получить позицию текующей точки на пути->target

Получить направление pc_position к target -> direction

Добавить направление * walkspeed к pc_postion

Проверить находится ли PC рядом с текущим положением на пути

Если верно, сдвинуть текущую точку по пути

Если текущая точка на пути является конечной, то прекратить движение персонажа

Актуальный код я использую здесь, в функции UpdatePath.

Анимация

Последний шаг – это отрендерить спрайт для персонажа и произвести анимацию спрайта в соответстви направления движения, выбранного игроком. Код, который реализует движение персонажа вдоль пути работает по направлению вектора, по которому перемещается персонаж, так что осталось сопоставить это направление с прорисовкой анимации.

Это пример арта, который я нашел на kafkaskoffee.com (я удалил зеленый бордюр в версии, которую я использую):

Имеем три позиции в состоянии покоя и три варианта анимации. Движение вправо может быть повернуто программно в коде для предостапвления четырех направлений в которых игрок может перемещаться: лево, право, вверх и вниз.

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

Я уверен, что есть способ лучше, но этот точно работает. Когда путь подходит к концу, конечный направляющий вектор используется для того, чтобы решить, какой из неподвижных спрайтов будет выбран.

Подведение итогов

Переведено на Нотабеноиде
http://notabenoid.org/book/31245/107985

Переводчики: silf, tobermori, KommissarRex

Настройки

Готово:

100.00% КП = 1.0