«Где карта, Билли? Нам нужна карта!»
м/ф «Остров сокровищ»
В прошлых выпусках мы уже обращались к теме стратегических игр. До сих пор рассматривались лишь действия на плоскости. Пришло время заняться стратегией в пространстве. Мы остановимся на генерации трехмерных ландшафтов и организации игровых действий, разворачивающихся на них.
Построение трехмерного ландшафта
Ландшафт в пространстве — это практически тот же природный ландшафт, окружающий нас в реальном мире. Он состоит из неровностей местности — гор, русел водоемов, долин.
Существует несколько основных принципов представления данных для хранения информации о ландшафтах в пространстве.
Первый — использование регулярной сетки высот (или еще другое название: карта высот — HeightMap).
Второй — использование иррегулярной сетки вершин и связей, их соединяющих (т.е. хранение простой триангулизированной карты).
Третий — хранение карты ландшафта, но в данном случае хранятся не конкретные высоты, а информация об использованном блоке. В этом случае создается некоторое количество заранее построенных сегментов, а на карте указываются только индексы этих сегментов.
Матрица высот. | Созданная пространственная сетка. |
Готовый ландшафт с натянутой текстурой и skybox. | Работа по холмовому алгоритму (Hill Algoritm). |
Плоская картинка — карта высот. Это будет один крупный холм и полукольцо мелких. |
Рассмотрим первый вариант — использование карты высот.
Данные представлены в виде двумерного массива. Уже заданы две координаты (для DirectX это x и z — по высоте и ширине массива), третья координата задается значением в конкретной ячейке — это высота y.
С помощью этого способа можно представить достаточно обширные пространства. Речь пока идет только про землю, без деревьев, домиков и прочих посторонних объектов. Самая простая карта высот (heightmap) представляет собой черно-белую картинку, в которой с помощью градации цвета указывается высота каждой точки: чем чернее точка, тем ниже ее положение относительно «уровня моря» (нулевой отметки), а чем белее, тем выше.
После построения карты высот (сделать это можно в любом графическом редакторе) ее следует преобразовать в 3D. Для этого создается сетка из полигонов, в которой каждая вершина связывается с соответствующей точкой в картинке и потом на эту картинку накладывается.
Вы можете сгенерировать трехмерную карту с регулярной сеткой с помощью одного из графических редакторов — например, Photoshop или Bryce.
Сгенерировать ландшафт можно по одному из алгоритмов — например, холмовому алгоритму (Hill Algoritm).
Работа с картой в пространстве
Сгенерированный ландшафт, сохраненный в формате DirectX, — это готовый материал для построения игровой карты. На него наносятся игровые фигуры, в том числе природные объекты — деревья, животные. Затем определяются правила игры.
Пустыня, растрескавшаяся земля. |
Морское дно. |
Делить трехмерные карты с видом сверху или же изометрические, как принято в классификации для плоских карт, не имеет смысла — обычно камера не закреплена жестко и есть возможность самому выбрать удобную точку обзора.
Предположим, мы хотим перемещаться по нашему ландшафту, как бы паря над ним, но не «проваливаясь» в землю, затем найти нужного нам персонажа и «вселиться» в него — взять его действия под свой контроль. Затем можно, управляя своим персонажем, погулять по карте в его теле.
Менять внешний вид карты можно также и с помощью текстур.
Для работы с готовой картой предназначен класс TLKI3DMap. Карта представляет собой неподвижный объект игрового мира со своей сеткой (mesh) и загружается из файла модели DirectX (формат .x). Для инициализации карты служит процедура init3DMap. При размещении объектов в игровом мире с инициализированной картой координата y (высота) вычисляется автоматически, исходя из карты высот для ландшафта данной карты. Например, можно высадить леса.
Альпийские луга. |
Некоторые места карты можно сделать непроходимыми. О реализации водоемов мы поговорим позже. Но ограничения на передвижение по неровностям ландшафта можно ввести уже сейчас. Достаточно проверить, как различаются по высоте точка текущего местонахождения персонажа и та, куда он должен попасть на следующем шаге. Если герой полезет на слишком крутую горку, то его можно и притормозить. Также могут ограничивать «проходимость» и «природные» объекты — дома, деревья, заборы.
Для «воздушных» объектов нужно проверять их положение относительно ландшафта. Если имеет место столкновение, то либо сажаем объект на карту, либо объект «разбивается».
Также есть возможность реализовать динамическое изменение ландшафта под воздействием различных внешних воздействий. Например, появление воронок после взрывов, рытье шахт и канав — понижение рельефа или его повышение — насыпание защитных валов.
Picking в «Звездном эскорте 3D» |
Потестировав нашу леталку-стрелялку, я добавил к возможностям нашего истребителя наведение на цель — противника — по щелчку мыши. Для этого использовал наш любимый механизм — picking. Разрешил обработку picking'а для врагов и переписал обработчик, вызываемый по факту выбора объекта по клику мыши. И вуаля — кликаем на цель — и истребитель автоматически берет ее на мушку. |
Добавляем Picking в SE 3D |
procedure TStarEscort3DWorld.IntersectActionExecute(objIndex : integer); begin //повернись к врагу лицом if (Objects[objIndex].ID = ALIEN1_ID) or (Objects[objIndex].ID = ALIEN2_ID) then begin TurnObjTo(SHIP_OBJECT_ID, objIndex); end; end; |
Надеюсь, так будет удобнее прицеливаться и истреблять инопланетян пачками. |