вторник, 28 октября 2008 г.

Оружейная. Делаем мину.

Говоря об оружии в целом, нельзя не вспомнить о всевозможных гранатах, бомбах и минах. Почему бы и нет? А давайте сделаем мину, которая будет тихо и спокойно лежать себе, пока на нее кто-нибудь по невнимательности своей не наступит. К слову сказать, мину сделать гораздо проще, нежели дубину, которую мы описывали в прошлой статье цикла "Оружейная".



Итак, для прообраза возьмем старую добрую, надежную противотанковую мину ТМ-46, изготовим ее из цилиндрических примов и приступим к самому главному - замесу взрывчатого вещества. ;)


Для начала давайте определим, от какого критерия должна срабатывать мина. Очевидно, что когда на нее кто-то наступит. Окей, берем уже известное нам по прошлой статье событие collision_start() и думаем дальше, что должно произойти после того, как нога аватара-раззявы наступит на наш "тортик".

Для разнообразия предлагаю использовать знаменитый push - llPushObject(). После того, как кто-то наступает на мину, мы вычисляем его идентификатор при помощи оператора llDetectedKey() и подкидываем вверх пушем:

llPushObject(llDetectedKey(0), force_amount*llRot2Up(llGetRot()), ZERO_VECTOR, FALSE).

В переменную force_amount поместим любое произвольное большое число - ну пусть это будет 10 000 000, не особо важно. Множитель же этой переменной - функция llRot2Up() от текущего значения вращения аватара на момент срабатывания мины - просто небольшая хитрость, смысл которой я не буду сейчас разъяснять. Просто запомните, что вектор импульса <0,0,10000000> работать не будет так же, как работает эта конструкция.

Можно сделать так, что мина будет срабатывать только на технику, например, на автомобили, или же, напротив, только на аватаров. Для этого нужно проверить, что именно вызвало событие - физический объект или аватар. Делается это при помощи оператора llDetectedType(). Например, нас интересует только живая сила врага. Значит, в скрипте пишем:

if(llDetectedType(0) & AGENT)
{
llPushObject(llDetectedKey(0), force_amount*llRot2Up(llGetRot()), ZERO_VECTOR, FALSE);
}


Кроме того, для совместимости с бэтлграундами неплохо добавить значение damage - пишем llSetDamage(5000).

Ну и осталось нам совсем немного - добавить спецэффектов, как то звук взрыва, дым, огонь и т.п. Кладем в инвентарь мины заранее подобранный звук и пару текстур, дыма и пламени. Звук вообще неплохо бы подгрузить заранее, поэтому рекомендую описать событие on_rez() и вставить туда команду заблаговременной подгрузки звука:

on_rez(integer start)
{
llPreloadSound("Explode");
}


Соответственно, звук нужно проиграть в нужный момент - добавляем перед пушем оператор llTriggerSound("Explode", 1.0), которая и проиграет звук, причем, звук будет как бы вокруг, а не четко привязан к самой мине, что важно в данном случае для нас - его будет далеко слышно.

Ну и дым с огнем. Тут с одной стороны все просто, а с другой - не очень. Дело в том, что существуют специализированные функции, которые призваны для того, чтобы создавать, особо не заморачиваясь, такие вещи, как взрывы, дымы, облака, брызги и т.п. Но отчего-то их вытесняют из языка LSL, предлагая использовать новомодную систему частиц llParticleSystem() во всех случаях жизни. Не буду спорить, система мощная, но работа с ней требует все-таки довольно глубокого понимания вопроса.

Итак, нужная нам команда - llMakeExplosion(integer particles, float scale, float velocity, float lifetime, float arc, string texture, vector offset). Немного расскажу про ее аргументы.

  • particles - количество частиц, которое будет сгенерено при вызове функции;

  • scale - максимальный размер частицы;

  • velocity - скорость распространения частиц;

  • lifetime - время жизни частицы;

  • arc - конус выброса частиц;

  • texture - текстура, которая будет натянута на каждую частицу;

  • offset - расстояние от источника до фактического образования частиц.



Итого, остается прописать два раза эту функцию - сначала для огня, затем для дыма:

llMakeExplosion(20, 1.0, 5, 3.0, 1.0, "Fire", ZERO_VECTOR);
llMakeExplosion(20, 1.0, 5, 3.0, 1.0, "Smoke", ZERO_VECTOR);


И самое последнее - раз мина взорвалась, то ее быть и не должно. Последней строчкой пишем llDie(), которое уберет сработавшую мину с земли.

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

Комментариев нет:

Отправить комментарий