130 (+1)

Падал новогодний снег

Как создать реалистичный снег на Flash
Общий алгоритм поведения снежинок
Пошаговое руководство для создания Flash-открытки

Поиск по сайтуДля желающих написать письмоПослать ссылку другуВерсия для распечатки




Часть II

Алгоритм поведения снежинок

Перед тем как заняться непосредственно физикой снегопада, давайте создадим внешний файл, в котором и будут находиться все необходимые функции. Запустите ваш любимый текстовый редактор (например, UltraEdit, но сойдет и Блокнот) и сохраните пока еще пустой файл под именем snow.as. Помните, мы уже подсоединили этот файл в первом фрейме нашей открытки? Далее мы начнем постепенно заполнять этот файл необходимыми функциями и переменными.


Физика поведения снежинок



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

// Постоянная составляющая скорости падения снежинки
_global.snowflake_y_gravity = 15;

В данном коде я определил глобальную переменную snowflake_y_gravity. Заметьте, что для определения глобальной переменной во флеше необходимо создавать ее как переменную объекта _global. Тогда данная переменная у нас будет доступна в любом месте нашего мультфильма.

Даже в очень спокойном воздухе постоянно возникают разнообразные небольшие вихри. Попробуйте подкинуть в воздух любой очень легкий предмет - перышко или шелковый платок - и Вы увидите, что горизонтально вниз он никогда не упадет. Наша снежинка даже легче перышка, и поэтому за счет этих микровихрей она может смещаться не только влево или вправо относительно вертикального падения, но даже иногда и немножко вверх. Мы учтем подобные микровихри, введя переменные смещения по вертикали (Yshift) и горизонтали (Xshift). А саму величину смещения будем вычислять как случайное число между нулем и максимально возможным смещением.

// Максимальный сдвиг снежинки по оси X и по оси Y
_global.snowflake_x_shift = 10;
_global.snowflake_y_shift = 10;

Но, кроме вихрей, случаются и настоящие ветры. Особенно это чувствуется в метель! Ветер мы учтем подобно гравитационной силе - как постоянно действующую силу в горизонтальном направлении (Wind). Знак этой силы будет указывать направление ветра.

// Скорость ветра
_global.wind_x_speed = 0;

Снежные хлопья бывают как маленькими, так и большими - за счет слипания нескольких снежинок вместе. Мы учтем этот фактор как случайное изменение размера снежинки (Sizeshift) относительно некоего базового размера.

// Ширина и высота снежинки
_global.snowflake_width = 11;
_global.snowflake_height = 10;

// Максимальное изменение размеров снежинки
_global.snowflake_size_shift = 2;

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

// Максимальное изменение прозрачности снежинки
_global.snowflake_alpha_shift = 10;

Пожалуй, мы учли все основные факторы, действующие на снежинку. Давайте подытожим и напишем окончательную функцию расчета нового положения снежинки (X0, Y0) относительно ее предыдущего местонахождения (X1, Y1):

    X1 = X0 + Gravity + Rnd(2 * Xshift) - Xshift
    Y1 = Y0 + Wind + Rnd(2 * Yshift) - Yshift

Размер новой снежинки и ее прозрачность мы также будем рассчитывать, основываясь на предыдущем состоянии снежинки, по следующим формулам:

    W1 = W0 + Rnd(2 * Sizeshift) - Sizeshift
    H1 = H0 + Rnd(2 * Sizeshift) - Sizeshift

    Alpha1 = Alpha0 + Rnd(2 * Alphashift) - Alphashift

Во всех формулах при расчете случайных величин я удваивал значения, т.к. сдвиг может происходить как в положительную, так и в отрицательную сторону. А для того чтобы затем выровнять положение, размер или прозрачность снежинки - вычитал величину сдвига. Этот способ как раз и позволяет нам учесть сдвиг значения в обе стороны.


Инициализация снегопада



Так как снегопад у нас состоит из многих снежинок, то мы должны отслеживать состояние каждой снежинки до тех пор, пока она окончательно не упадет или не вылетит за пределы снегопада. Для хранения этой информации мы организуем массив снежинок, причем информация обо всех пяти параметрах каждой снежинки также будет храниться в массиве.

// Количество падающих снежинок
_global.num_snowflakes = 30;

// Массив, хранящий описание снежинок
_global.snowflakes = new Array(num_snowflakes);
for (i=0; i<num_snowflakes; i++) {
    snowflakes[i] = new Array(0,0,0,0,0);
}

Для учета того факта, что снежинка достигла земли или вылетела за пределы снегопада, нам необходимо определить координаты габаритного прямоугольника, определяющего снегопад. Координаты левого верхнего будут (0,0), а координаты правого нижнего угла совпадут с шириной и высотой нашей открытки.

// Ширина и высота снегопада
_global.snow_width = 640;
_global.snow_height = 300;

Перед тем как мы начнем отрисовывать снегопад, нам необходимо заполнить массив снежинок начальными данными, а также программно сгенерировать мувиклипы для всех снежинок. Мы оформим данную процедуру в виде функции init_snowflakes():

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
//                      Функция инициализации снежинок                       //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

function init_snowflakes() {

    for (i=0; i<num_snowflakes; i++) {

        // Создаем новый экземпляр снежинки
        snow.attachMovie("snowflake", "snowflake_"+i, i);

        // Инициализируем снежинку начальными значениями
        snowflakes[i][0] = random(snow_width);
        snowflakes[i][1] = random(snow_height);
        snowflakes[i][2] = snowflake_width;
        snowflakes[i][3] = snowflake_height;
        snowflakes[i][4] = random(30);
    }
}

В процессе инициализации мы создаем новые мувиклипы, на основе нашей снежинки, помещенной в библиотеке. Помните, при сохранении мы назвали ее snowflake? Теперь именно этот идентификатор используется для создания новых экземпляров снежинок. Каждый новый экземпляр должен быть прикреплен к уже существующему объекту, и именно точка привязки этого объекта будет началом координат для нового мувиклипа. В качестве родительского объекта мы поместили саму же снежинку в верхний левый угол открытки, дав ей имя snow. И таким образом обеспечили совмещение координат снегопада с координатами открытки.

Для создания нового экземпляра мувиклипа в ActionScript используется метод attachMovie(), вызываемый из родительского объекта. Синтаксис данной функции следующий:

my_mc.attachMovie(idName:String, newName:String, depth:Number [, initObject:Object]),

где

  • idName - идентификатор объекта, из которого создается новый экземпляр
  • newName - имя нового экземпляра создаваемого объекта
  • depth - Z-координата создаваемого мувиклипа, определяющего порядок отрисовки объектов на сцене
  • initObject - объект, атрибуты которого будут присвоены создаваемому мувиклипу

Для генерации случайного целого числа в ActionScript используется функция random(). В качестве параметра ей передается целое число N, а в качестве результата возвращается случайное число R в диапазоне 0 < R < N-1.


Часть 1Часть 2 - ее Вы читаете сейчасЧасть 3Часть 4


Свои мнения, пожелания и вопросы по выпускам Вы можете присылать по адресу mike@cherry-design.ru.
Я оставляю за собой право цитировать письма, пришедшие по вышеуказанному адресу.
Copyright © 2001-2008 Михаил Мельников. Перепечатка без разрешения запрещена.