Алгоритмы используемые в играх.
Эти широко известные игры, такие как "Leisure Suit Larry", "Loom", имеют, на первый взгляд, схожий с предыдущим типом алгоритм. Здесь герой вроде бы также осуществляет поиск в некотором пространстве необходимых предметов и пытается добраться до конца некоего лабиринта ситуаций. Отличия заключаются в наличии персонажей, с которыми надо общаться - поговорить, что-то узнать; в запутанном порядке достижения цели - пока что-то не сделал, дальше не продвинуться; и в связи с этим с необходимостью исследования игрового пространства. Кроме того, принципиально отличная от “Платформ и лестниц” организация интерфейса, основанная на диалоговом, подчас чисто словесном общении, делает внутреннюю структуру этого типа программ достаточно оригинальным.
Мы рассмотрим схему игр типа Adventure, построенную по следующему принципу: герой может перемещаться в пределах одного экрана, точнее, локации, которая во всяком случае не сильно превосходит экран. Это одно из отличий от Arcade, где размер одного лабиринта достаточно велик. В Adventure таких локаций, как правило, бывает до нескольких сотен. Все они могут быть взаимосвязаны друг с другом, например, в десятой локации для открытия двери герою потребуется ключ, который необходимо было отыскать в пятой локации.
Кроме простых аркадных передвижений вперед-назад, игроку предоставляется набор возможных действий, которые можно попробовать применить к любому предмету данной локации. Выглядеть это может либо “тыканием” мышкой в разные точки экрана - шкаф, пульт управления, домик, или простым перемещением курсора, который может меняться в зависимости от своего положения над тем или иным объектом на экране. К различным объектам вы можете применить различные действия; понятно, что для одних предметов никакой реакции не последует, в других случаях вы можете добиться желаемого результата. Например, в одной из старых текстовых игр для UNIX к вам прицеплялся некий злой колдун, которого не уничтожали никакие воздействия типа “застрелить”, “сжечь”, “удрать” и т.п. Оказалось, к нему надо было применить действие “съесть”! Вот все эти нюансы игр-головоломок мы и постараемся проанализировать.
Базовый массив (LxNxM) определяет набор из L локаций, каждая из которых в принципе повторяет структуру лабиринта игр Arcade, только образ ее на экране более закамуфлирован. Это может быть площадка из домиков среди гор, причем переходами в другие локации являются входы в домики, тропинки между горами и так далее, как, например, в "Loom". При этом функции стен выполняют такие элементы дизайна, как подножия гор или просто промежутки между проходами, недостижимые в игре.
Сложность таких псевдолабиринтов низка, она не является самоцелью, а лишь выполняет вспомогательную цель приближения экранного образа к реальному. Но они выполняют важную в адвентюрах роль виртуального пространства, которое играющий должен исследовать. Более важными в схеме алгоритма является описание и хранение тех событий и/или объектов, которые должны встретиться в данной локации. Это могут быть спрятанные в разных местах бананы, как в "Secret of" "Monkey Island I", или препятствия, которые можно преодолеть с помощью различных приспособлений, таких как бюстгальтер в “Страстной Патти”. Они кодируются определенными значениями в массиве, но не всегда отображаются на экране, например, пока герой не выполнит некоторого действия-исследования в данной точке типа “посмотреть повнимательнее” или если герой не имеет с собой предмета, активизирующего данное событие. Например, процесс поиска Инди Джонсом ключа в доме Генри может быть запрограммирован примерно так:
// Игрок выбрал действие “искать” в некоторой точке Point (с помощью // мыши или другим способом): KEY_SEARCH: // если в текущей локации в точке Point // расположена мебель, а за ней ключ ... if( Game[ CurrentLoc ][ Point.X ][ Point.Y ] == FURNITURE_AND_KEY ) { // изменить в локации значение “ключ за мебелью” на // “просто мебель”: Game[ CurrentLoc ][ Hero.X ][ Hero.Y ] = FURNITURE; // Герою добавить ключ: Hero.Key = TRUE; // Перерисовать изменения на экране ... }
Второй особенностью адвентюр является установление контактов с различными персонажами игры для получение информации о дальнейших действиях. Например, в "Heart of China" Счастливчику Джону надо несколько раз поговорить с ламами, чтобы найти правильный путь в Катманду, кроме того, его успешные диалоги с Кейт являются ключевым залогом того, что они в итоге поженятся в Париже.
Подобные игровые ситуации протекают следующим образом. Когда герой приближается к некоторой точке текущей локации, это вызывает определенное событие, не требующее вмешательства игрока. В "Space" "Quest I" в начале игры, когда Роджер Вилко заходит в архив с картриджами, в комнату вползает смертельно раненый ученый и говорит “ASTRAL BODY”. Эта информация в ближайшем будущем окажется кодом для ввода в компьютер. Еще раз отметим, что в моменты получения игроком информации от персонажей игры вмешательства человека не требуется. Он должен лишь внимательно наблюдать и запоминать выводимый на экран текст (как правило, речь персонажа). Но для инициализации подобных сюжетов служат специальные команды типа вводимого слова “SPEAK” или выбора мышкой пиктограммы “ГУБЫ”.
Подобным же образом программируются и другие игровые моменты. К примеру, когда в игре "Loom" вы в городе кузнецов заходите в комнату с печью, то появляющийся мастер запирает вас там в кладовке на ночь. Это может выглядеть так:
{ если герой около точки с печью ... } if Around( Game[ CurrentLoc, Hero.X, Hero.Y ], Stove.Pos ) and { ... и в точке ПЕЧКА значение “Герой-появляется-в-первый-раз” } (Game[ CurrentLoc, Stove.X, Stove.Y ] = STOVE_NEW) then begin { показ сюжета с появлением мастера; } { В точку ПЕЧКА записать значение “Мастер-прошел” } Game[ CurrentLoc, Stove.X, Stove.Y ] = STOVE_OLD; end;
В дальнейшем по значению “Мастер-прошел” можно определять, на каком этапе находится развитие сюжета в данной локации.
Конечно, этот подход является слишком общим. На практике программисты упрощают процесс, например, такой мультфильм запускается каким-либо событием в игре, скажем, не подходом к печке, а просто первым входом в данную локацию - соответствующая проверка проводится на стадии инициализации локации.
Сам объект ГЕРОЙ содержит в себе большое количество флажков, определяющих наличие у героя тех или иных вещей, а также его возможное здоровье и прочую вспомогательную информацию. Здесь содержится такая информация, как наличие у Роджера Вилко картриджа в "Space Quest I" или флейты у Брандона в "The Legend of Kyrandia I".
В играх данного типа, как правило, нет автономно движущихся объектов, как в Arcade. Вы редко встретите здесь монстров, разгуливающих по горам, или роботов, бесцельно болтающихся по отсекам звездолета. Все сценки встреч обычно заранее предопределены, и проигрываются на экране, как простые анимационные вставки без вмешательства со стороны игрока. Хотя нельзя забывать и о том, что герой игры нередко может в этих сценах стартовать диалог или же применять какие-либо предметы. Кроме того, для игр в концепции “виртуального театра” “полубестолковое” движение персонажей вполне возможно и даже почти обязательно. Существует также такое семейство игр, как “аркадная адвентюра”, к сожалению редко встречающееся на IBM-совместимых машинах, хотя по технологии программирования они скорее попадают в раздел, посвященный жанру Arcade (см. выпуск N7).
Особой характеристикой адвентюрных игр является достаточно большой список действий, которые можно попробовать применить к любым точкам текущей локации, ограниченной, как правило, одним-двумя физическим экранами. Иногда определенному предмету (или позиции, характеризующей некоторый сюжет) на экране соответствует только ему определенный список действий. Для револьвера это может быть “взять”, “положить”, “стрелять”, “перезарядить”. В программе это можно легко реализовать, например, с помощью массива, номерам строк в котором соответствуют внутренние номера предметов в игре, распределенные по главному массиву текущей локации, а значением каждого элемента в строке является код некоторого действия, которое нужно выполнить. Это действие имитируется уже конкретным программным путем.
Способы организации интерфейса человека с персонажами игры мы не будем здесь рассматривать. Это может быть простая строка для ввода текстовой информации (типа “use little flag on little hole” в "Future Wars" для использования найденного в туалете флажка) или выбор мышкой пиктограммки РОТ и РУКА в "ECOQUEST II" для разговора с отцом и вытаскивания из ящика Экорекордера. Вы можете пробовать самые невероятные сочетания действий с предметами для нахождения единственно верного в данной ситуации решения.
Сложность алгоритма Adventure-игр заключается в том, что все уровни игры необходимо определить заранее, они практически не содержат случайных элементов, влияющих на ход сюжета. Рассмотрим алгоритм подробно на примере организации интерфейса с человеком с помощью мыши.
- Загрузить новую локацию.
- Ожидать перемещения мышки или нажатия ее кнопки.
- Если мышка расположена над xy-полем игрового массива с непустым значением, то вывести соответствующую информацию о наличии в данном месте экрана определенных возможностей, иначе стереть старую информацию.
- Если нажата кнопка мыши над пустым полем, доступным герою, то переместить его в новую позицию.
- Если нажата кнопка мыши над непустым полем, то при наличии включенных флажков совершить соответствующее действие (открыть дверь, взять предмет, вывести необходимый текст).
- Если выбрано определенное действие из списка возможных, то проверить положение героя в нужной точке для выполнения данного действия и наличие необходимых вещей для изменения обстановки и откорректировать соответствующие переменные. При необходимости проиграть соответствующий сюжет.
- Перейти к п.2.
Разумеется, наши читатели понимают, что приведенный алгоритм представляет собой предельно упрощенный вариант. В большинстве современных игр используются более сложные алгоритмы: во-первых, дело может несколько усложниться постоянной фоновой анимацией - типа горящих огней, развевающихся флагов и еще чего угодно - вы видели это много раз. Во-вторых, часто встречаются экзотические отклонения - типа ситуации “не трогай крысу” в "Secret of Monkey Island I". В-третьих, в такой алгоритм не вписываются действия, ограниченные по реальному или псевдореальному времени, а также действия пользователя в рамках активного мультфильма - типа “битвы” со снежным человеком в "King's Quest V".
Сложность проектирования игр жанра Adventure заключается, в первую очередь, в выдумывании головоломного сюжета и тщательного продумывания значений всех игровых переменных и их сочетаний. Сам процесс программирования этого типа игр не очень сложный.
Оценка сложности собственно программирования:
4 из 10, но это не означает, что создание этих игр является делом простым, поскольку
основная трудоемкость падает на графическую, сценарную и звуковую поддержку.