Так, где же был весь наш снег в это рождество? Все, начиная от нас и заканчивая QA, задавались тем же самым вопросом. Но jbeta выручил нас со следующей хорошей вещью...
MTA снег! Да действительно, это настолько же легко, насколько это звучит!
В основном скрипт, который создаёт искусственный снег вокруг игроков, когда они набирают команду в консоли. Скрипт так же позволяет изменять радиус, плотность, скорость и размер вашего снега, позволяя добиться желанного эффекта.
Обучающее видео: scriptvideo2.avi - XviD codec (640x480, 30fps, 7mb)
Готовый скрипт: script2.lua

Для начала, давайте создадим таблицу,
snowflake = {} --Это инициализирует таблицу IDs снежинки |
За дополнительной информацией о Lua и её таблицах, я советую вам обращаться к официальной документации
а затем мы создадим некоторые глобальные переменные:
flakeID = 1 -- Это устанавливает ID первой снежинки на 1 updaterate = 27 -- Позиции, частота обновления в миллисекундах height = 4 -- Начальная позиция снежинки над головой игрока snowing = false -- Эта переменная сообщает скрипту идёт ли снег или нет. |
В прошлом руководстве мы узнали, что вы можете использовать функцию addEventHandler чтобы привязать ваши функции к событиям MTA. Однако этот скрипт использует команду в консоле для вызова функции. Для этого есть подобная функция под названием addCommandHandler:
addCommandHandler ( "snow", "snow_SnowCommand" ) |
Это привязывает команду "snow" в коносле к функции "snow_SnowCommand", подобно функции addEventHandler.
function snow_SnowCommand ( player, commandname, radius, density, speed, size ) |
Функция addCommandHandler автоматически задаёт две переменные к функции, к которой она привязана. Это переменные "player" (игрок) и "commandname" (название команды). Любые другие аргументы будут задаваться как дополнительные переменные.
Например, если пользователь должен был бы напечатать "snow 4 3 2 1" в консоле, то команда задавалась бы так:
игрок, который напечатал команду, "snow", 4, 3, 2, 1
соответствие функции выше.
Команда сделана так, чтобы когда пользователь написал "snow" в консоле, снег был бы создан.
if not snowing then |
Если снег уже не идёт, начните функцию snow_CreateSnow. Также отметьте функцию getClientName. Это в основном восстанавливает имя указанного игрока.
Команда так же сделана так, чтобы если снег уже падает и затем набрать команду "snow" в консоле, он прекратился:
else snowing = false --устанавливает переменную snowing на выключено (false) outputChatBox ( "Snow stopped." ) --оповещает о том что снег был остановлен end end |
Скрипт использует функцию snow_CreateSnow. Это не одна из стандартных функций MTA, скорее пользовательская функция:
function snow_CreateSnow ( player, radius, density, speed, size ) |
Скрипт создаёт снег вокруг игрока, который ввёл команду. Поэтому мы должны получить местоположение игрока:
local px, py, pz = getElementPosition ( player ) |
В прошлом руководстве мы рассматривали setElementPosition. Эта функция используется для получения позиции игрока и затем установления её - в этом случае она будет определяться с переменными px, py, pz.
--Если игрок недействителен или разъеденился, остановить функцию if not px or not py or not pz then snowing = false return end |
Эта часть скрипта проверяет, разъединился ли игрок или ушел. Это сделано проверкой, недействительны ли переменные px, py или pz. Если это действительно так, тогда это должно быть, потому что в некотором роде игрок не существует.
Следующая секция скрипта, обращается к параметрам, которые не определены. Например, если пользовать напечатает только "snow" без определения радиуса, плотности, скорости или размера, тогда они будут стандартными.
-- Если какой-нибудь параметр не будет задан, то скрипт даст параметр по умолчанию if not radius then radius = 20 else radius = tonumber ( radius ) end |
Если радиус не существует, то стандартное значение равняется 20. Если этого действительно не существует, преобразуйте это в число от типа (string) используя функцию lua tonumber.
if not density then density = 3 else density = math.ceil ( tonumber ( density ) ) end |
Точно так же, если плотность не была определена, то стандартное значение будет, равняется 3. Если этого действительно не существует, преобразуйте это в число от типа (string) и используйте lua функцию math.ceil для округления числа до целого числа.
if not speed then speed = 1.5 else speed = math.abs ( tonumber ( speed ) ) end |
Это использует функцию LUA math.abs, чтобы вернуть абсолютное или положительное число.
Для получения дополнительно информации о math.abs и math.ceil, пожалуйста, посмотрите официальную документацию.
if not size then size = 0.15 else size = tonumber ( size ) end |
Наконец, выставление стандартного размера, если он не определён.
Затем мы используем lua как цикл, для создания настолько большого количества снежинок насколько хотим. Для этого используется переменная density (плотность) которая была определена раннее, чтобы создать каждую снежинку. Это в основном цикл для: счётчик > плотность (counter > density).
local counter = 0 --Мы будет повторять процесс создания снежинок в одно время со снежинкой while counter <= density do |
-- Для x и y, мы вычислим случайную позицию вокруг игрока, |
Здесь мы используем тригонометрию, чтобы получить случайную позицию для помещения снежинок. Сначала мы используем randInt Lua для получения случайного целого числа между 0 и 359 - то есть и угол. Затем мы используем тригонометрию на углу, чтобы получить позицию x и y и умножить её радиусом (radius) определённым ранее. Тогда это будет умножено значением между 0 и 1 (randFloat), для получения случайной позиции в пределах радиуса.
Теперь мы имеем позицию, давайте фактически создадим снежинку
snowflake[flakeID] = createMarker ( fx, fy, fz, "corona", size, 255, 255, 255, 150 ) |
Это использует функцию createMarker. В прошлом руководстве мы использовали эту функцию с типом "цилиндра" ("cylinder") для создания цилиндрического маркера. Этот тип создаёт маркер "короны" ("corona") который является своего рода "горящей окружностью". Это также добавляет маркер к таблице снежинки, таким образом, это может быть восстановлено позже.
--Мы вычисляем время, которое требуется для снежинки, чтобы упасть, в миллисекундах local time = 1000 * ( height + 1 ) / speed --Мы говорим скрипту обновлять снежинку столько раз сколько необходимо записать |
Когда вычисление сделано, решите требуемое время - используя: время = расстояние / Функция setTimer используется для вызова функции после определённого времени.
скорость (time = distance / speed).
Функция setTimer используется для вызова функции после определённого времени.
В этом случае вызывается два таймера. Одна для перемещения снежинок вызывая snow_moveFlake согласно норме обновления позиции снежинки, а другая уничтожает снежинку, после того как время истекло.
--Повторять эту функцию снова через секунду, если снег всё же включён if snowing |
Наконец, мы вызываем функцию, чтобы создать снег снова через одну секунду и закончить функцию.
Следующая функция snow_moveFlake.
function snow_moveFlake ( flakeID, speed ) local fx, fy, fz = getElementPosition ( snowflake[flakeID] ) setElementPosition ( snowflake[flakeID], fx, fy, fz - ( updaterate / 1000 * speed ) ) end |
Это восстанавливает позицию снежинки, ища её в таблице. Тогда это перемещает вниз, вычисляя согласно скорости и норме обновления. Так как это многократно вызывается согласно норме обновления с таймером, который мы установили выше, кажется что перемещается.
Напоследок мы имеем функцию snow_destroyFlake, которая уничтожает снежинку после истечения времени. Эту функцию вызывается с помощью таймера выше.
function snow_destroyFlake ( flakeID ) destroyElement ( snowflake[flakeID] ) snowflake[flakeID] = nil end |
Мы использовали ту же самую функцию в прошлом руководстве, destroyElement, для разрушения маркера то есть снежинки. Тогда мы очищаем снежинку из таблицы.
Вы думаете на этом всё? На данный момент да. Ждите дальнейших обновлений на нашем сайте.