Творец. День первый. Твердь земная и небесная

Я думаю, вы уже успели переписать весь листинг из предыдущей статьи и теперь имеете приложение, которое загружает уровень из файла и отображает его на форме. Теперь пора подумать о том, как сделать стены твёрдыми, а воздух – прозрачным.

Естественно, данную задачу нужно решать с помощью физического движка. И на этот раз нам ничего не придётся разрабатывать, поскольку физические движки для GLScene существуют в изобилии. Обратимся к стандартному обработчику физики для GLScene – DCE Manager.

Ньютон в памперсах
Конечно, есть движки на порядок мощнее – ODE или Newton. Однако я не думаю, что для нашей игры понадобится обработка rag-doll-анимации или взаимодействия различных частей автомобиля (привет движку Newton).
DCE является упрощённым вариантом физического движка ODE, однако это не мешает использовать его в качестве отличного помощника для программистов начального уровня. Итак, что же он умеет? Товарищ DCE специализируется на двух типах тел – статика и динамика. И те, и другие являются твёрдыми, поэтому особого разнообразия ждать не приходится. Для каждого типа можно указывать следующие свойства: трение, упругость, тип твёрдой оболочки. Для статичных объектов выбор большой: это может быть примитив или сложная оболочка. А вот динамика нас так не балует – вокруг динамического объекта можно построить оболочку только в виде параллелепипеда и задать его размеры.

Бросаем яблоко
Давайте теперь поэкспериментируем с замечательной наукой физикой и попытаемся реализовать её в нашей игрушке. Чтобы все известные физике законы работали, нужно добавить на форму новый компонент – GLDCEManager из вкладки GLScene Utils. Переименуйте его в PhysManager. Покопаемся в свойствах: Gravity должно быть равно «-9,8» (на Земле всё-таки находимся). Теперь можно использовать доселе неизвестное свойство у всех 3D-объектов – Behaviour. Это свойство содержит в себе список всех прикрученных к объекту возможностей игры – к примеру, это может быть звук или различные физические свойства.

Я надеюсь, у вас открыт проект с игрой? Добавьте новый объект GLSphere (или используйте тот, который остался с первой статьи) и откройте свойство Behaviour (щёлкните по кнопке в виде многоточия рядом со свойством). У вас появилось окно GLSphere1.Behaviour. Щёлкайте по кнопке в виде плюсика и выбирайте в выпадающем списке DCE Dynamic Collider. Этот физический обработчик теперь появился в списке Behaviour. Щёлкаем по нему и меняем следующие свойства: Manager=PhysManager и Friction=2 (трение). Масса вычисляется из объёма и коэффициента трения. Теперь сфера имеет физическую оболочку.
Пора прикрутить физику и для нашей карты. Ищем строчку cube:=TGLCube.CreateAsChild(GLLevel); и после неё добавляем:

with GetOrCreateDCEStatic(cube) do
begin
 Manager := PhysManager;
 BounceFactor := 0;
 Friction := 3;
 Shape := csBox;
end;

Каждый кубик уровня стал твёрдым. Как вы поняли, сфера пока что будет символизировать собой игрока. В INI-файле подредактируйте матрицу уровня и замените какой-нибудь нулик на «p»(без кавычек конечно же). Теперь добавим в раздел case line[k] ofследующий блок кода:

'p':
 begin
  GLSphere1.Position.Y:=I;
  GLSphere1.Position.X:=k;
 end;

При запуске программы сфера встанет на место игрока и будет послушно падать вниз. Возможно, сфера в каком-то месте застрянет, хотя никаких видимых препятствий не будет. Это может случиться сейчас или тогда, когда вы захотите усложнить карту уровня. Вам нужно уменьшить значения свойств Size.X, Size.Y, Size.Z для DCE Dynamic Collider сферы.

Make-up
Теперь давайте наведём небольшой порядок в нашем коде. Дело в том, что при создании формы приложения мы загружаем уровень. Но ведь уровень может загружаться и в любой другой момент работы программы. Поэтому весь код из процедуры Form1.FormCreate нужно занести в отдельную процедуру собственного изготовления LoadMap с параметром level_name: string. В процедуре заменим строчку

level:=TINIFIle.Create(GetCurrentDir+'\Levels\level1.ini');

на

level:=TINIFIle.Create(GetCurrentDir+'\Levels\'+level_name);

Эту процедуру теперь можно вызывать из любого места кода. В процедуре Form1.FormCreate должно остаться:

LoadMap(‘level1.ini’);

Театральный кружок
Как я и обещал, в скором времени мы займёмся действительно серьёзной 3D-графикой. Ведь теперь нам надо научить главного героя послушно двигаться согласно нашим командам, а монстров – согласно неведомым силам искусственного интеллекта. Чтобы наши нарисованные товарищи это умели, в следующий раз мы рассмотрим новый объект – GLActor, так сказать, безликого актёра наших театра.


Рекомендуем почитать: