25 января 2011

glVehicles-Gibbets или насколько трудно программировать физику?

Снова я... И сразу же - ура! обновления в репозитории! добавилась еще одна демка! Правда еще пару дней назад я не планировал делать то, что получилось. Отчего такая спонтанность? Ну, немного предыстории...
Недавно закончился 11ый конкурс на glscene.ru и в данный момент подводятся итоги. Конкурс выдался на редкость замечательным! Большое количество участников, высокий уровень работ, интересные находки в плане геймплея... супер! Без шуток! Рад, что довелось оценивать работы конкурсантов! 
Теперь происходит выбор новой темы для следующего конкурса... Как всегда я предложил выбрать для темы игровую механику какой-нибудь флеш-игры. Среди них есть множество действительно чумовых! На мое удивление, прозвучала фраза, что это сложно и только с виду выглядит простым. Наверно, это задело мое самолюбие и я решил продемонстрировать, что программирование физической основы игровой механики предложенных мною игр не столь трудно, как представляется... завернул мощно, ничего не поделаешь, но суть проста - я попробовал запрограммировать что-то из тех физических штук, что я предложил...
Предыстория закончена, теперь к делу... Итак, выбор пал на Gibbets. Игра простая - стреляем из лука, стрелы физические, втыкаются в предметы. Цель - перерезать веревку у висельников, чтобы спасти несчастных.
Код простой, но нагромождается обильными методами вроде AddArrow(), LaunchArrow(), AttachArrow() и т.д. Скрин (стрела слева-внизу, указывает на курсор мыши):


А вот я уже немного "пострелял":


Сила выстрела зависит от удаленности мыши от изначального положения стрелы. Чем дальше мышь - тем сильнее выстрелит стрела.
При программировании полета стрелы оставалась одна проблема - допустим, вы кидаете палку, какова вероятность того, что она будет красиво лететь, причем ударится о землю именно своим наконечником? Оказалось, невелика. Что-то я крутил-вертел физические свойства стрелы (массы наконечника и основания, начальную скорость, сопротивление воздуха и т.д.) - ничего не получалось. Затем я решил сделать грубо - выставлять ориентацию стрелы в зависимости от её линейной скорости. Но решение мне показалось "некрасивым". В итоге я глянул, как сделано в оригинальных Gibbets и узрел тот же самый "грязный хак" - ориентация выставляется вручную. "Тому и быть" - подумал я и дописал маленький метод CorrectDirection() для более красивого полета стрелы. Сам код выглядит так:

Procedure TfrmDemo8.CorrectDirection;
var
  vel: TVector;
  ang: Single;
begin
  vel := fArrow.Velocity;
  if (fArrowJoint = nil) and (fAttachJoint = nil) and (sqr(vel[0]) + sqr(vel[1]) <= 10) then
  begin
    ang := ArcTan2(vel[1], vel[0]);
    fArrow.Rotation := ang;
  end;
end;

Как видите, ничего сложного. "Достали" линейную скорость, посмотрели, в полете ли сейчас стрела, если да - выставили угол поворота тела. С бубном бегать не пришлось - а это уже хорошо :)
А вот небольшое видео моей "пострелялки":



Веревку пока добавлять не стал, ибо нет на это времени... но это не сложно, поверьте!
Итак, glVehicles не заброшен! Не падать духом, господа! Основа для 8ой демки имеется, сейчас 20ая ревизия. Обновляемся, компилируем и в путь! Опять же, так как мало кто любит качать что-либо из репозиториев, поэтому я выложил итоговый ехе для тестов отдельно...

Вот как-то так)).. до новых встреч!

Сообщения, схожие по тематике: