Море воды - программная анимация и не только
05.05.2008, автор Stormit, рубрики: ActionScript, Flash игры, Анимация, Игровые баннерыВесна радует хорошей погодой, да и лето уже не за горами, поэтому для многих может стать актуальной задача создания во флеше моря, озера, реки или иного водоема.
Анимировать воду не так-то просто - это скажет каждый, кто хоть раз пытался это сделать. На первый взгляд эта переменчивая структура ведет себя непредсказуемо и пытаться воссоздать ее - пустая трата времени (действительно, некоторые считают что если он не Айвазовский, то даже браться за это не стоит). Но это только на первый взгляд. Главное, чтобы в готовом виде клип мгновенно определялся пользователем как вода и вел себя соответствующим образом. Конечно, можно вставить в игру видео, а можно сделать все гораздо экономичнее.
Здесь собраны самые разные примеры анимации воды, которые я насобирал, пройдясь по своим работам. В основу этих примеров положен тот факт, что у воды есть волны. Осталось только хорошо их изобразить. Все они имитируют волны, только каждый по-своему. Наверное, точнее будет сказать, что эти примеры отличаются по стилю.
Теперь распишу каждый пример подробно.
Первый пример кажется самым простым, но для меня он наиболее интересен. Я вообще плоские цвета люблю больше, чем градиенты. Они выглядят мультяшнее (веселее) и с ними удобней работать (нет стыков при наложении).
Здесь Actionscript используется наравне с обычной анимацией. Создается клип с анимацией движения одной волны и потом он раскидывается каждый кадр по площади моря. Когда волна угасает, в последнем кадре анимации вызывается скрипт, который удаляет этот дубликат.
- Создаем прямоугольный символ box - это рабочая площадь моря. Дальше рисуем “барашка” - пену которая возникает на пике волны. Помещаем ее в клип wave и анимируем полный цикл - волна появляется и уходит с замедлением в наивысшей точке (можно просто сжимать клип по вертикали, а можно при этом стараться сохранять массу). В последнем кадре клипа wave пишем строку для удаления:
this.removeMovieClip();
- Слоем выше на кадре пишем такой код:
lev = 0; var w = box._width; var h = box._height; onEnterFrame = function() { lev++; var d = wave.duplicateMovieClip("d" + lev, lev); d._x = box._x + Math.random() * w;//ложим в случайную точку d._y = box._y + Math.random() * h;//на поверхности воды d._xscale = d._yscale = 50 + Math.random() * 100;//больше реализма }
- Море в готовом виде. Похоже на легкий бриз в ясную погоду.
- Но это всего лишь принцип, делать так можно не только море. Например, в этом примере что-то похожее на кислоту, а вместо волн - пузыри с ядовитым газом. Думаю всплески от дождя и мигание звезд тоже неплохо получатся.
Пример №2. Простой трюк для придания глубины - как в кукольном театре. Создается символ волны, с лихвой перекрывающий экран, смещается на половину ширины и возвращается в начальное положение. Ничего нового тут нет, все было расписано в программной анимации фона. Волна дублируется несколько раз и для каждой прописывается своя скорость - чем дальше, тем меньше ( и в размерах тоже).
- Символ длинной волны можно создать из маленьких кусков. Зазоры между ними изображены для наглядности, в жизни все должно быть вплотную.
- Так как код для всех волн одинаковый, лучше его писать внутри клипа волны.
x0 = _x; x9 = x0 - _width / 2; onEnterFrame = function() { _x -= speed;//скорость задается снаружи var dx = x9 - _x; if (dx > 0) { _x = x0 - dx; } }
- А переменная speed снаружи задается для каждой волны индивидуально. По простому, на клип, через onClipEvent:
onClipEvent (load) { speed = 3.5;//для верхнего клипа }
- Должно получиться примерно так. Можно сильнее детализировать море дополнительными волнами. Кораблик раскачивается синусом.
Пример №3 тоже создает волны, но совсем иного типа. Похоже на эффект из фильма “Хищник”. Есть две одинаковые текстуры воды, смещенные по координатам. Причем нижняя просто лежит на сцене, а верхняя проявляется случайным образом.
- Берем любую однородную “бесшовную” текстуру воды.
- Вызываем для нее Break Apart (Ctrl + B). Теперь белой стрелкой (Subselection Tool) раздвигаем точки до размеров флэшки.
- Рисуем и анимируем примерно такой полумесяц, как в примере (у меня эта анимация длится 25 кадров). Это будет рядовой Волна. Внутри нее в первом кадре пишем код, который выполнится один раз и начнет проигрывание с произвольного кадра:
if(!_first) { _first = true; gotoAndPlay(Math.floor(Math.random()*_totalframes)); }
- Формируем из волн “отделение” - заполняем прямоугольную область. Из отделений - взвод, роту, батальон, полк и так далее, пока не заполнится весь экран. Можно, конечно, весь экран закидать одиночными символами, но так гораздо дольше и изменять потом тяжелее.
Поместим весь набор, который занимает экран в символ wave1. Дублируем его и располагаем выше (символ wave2), зазора между ними быть не должно. Анимировать волны будем таким способом: обе волны смещаются вниз с одинаковой скоростью и как только нижняя скрывается за экраном, тут же перескакивает наверх. На первой волне пишем код:onClipEvent (load) { y0 = _y;//запомним координату и привяжемся к ней onEnterFrame = function() { _y += .5; if(_y > 175) _y = y0; } }
На второй:
onClipEvent (load) { y0 = _parent.water1.y0;//вот и привязались onEnterFrame = function() { _y += .5; if(_y > 175) _y = y0; } }
Должно получиться что-то похожее. как на примере.
Лимит по _y я подобрал вручную - габариты клипа постоянно меняются и к ним сложно привязаться. - Вот так в рабочем режиме покрывают весь экран
- Воду, созданную на шаге 2 дублируем и ложим слоем выше. Смещаем на 5 пикселей вниз. Клип со всеми волнами становится для нее маской (во избежание проблем, в масочном слое должен быть всего 1 клип).
- Должно получиться примерно так. Поиграться можно с размером микроволн, плотностью заполнения, длительностью анимации.
Пример №4 - не совсем волны, но эффект каустики во флэше. Здесь почти без скриптов. Способ больше подходит для “вида сверху”.
- Берем любую однородную “бесшовную” текстуру воды.
- Создаем море размером с экран (а по высоте в 2 раза больше). Break Apart (Ctrl + B), и белой стрелкой (Subselection Tool) раздвигаем точки до размеров сцены. Слоем выше лежит копия моря, повернутая на 180 градусов и простым твиннингом уходит в альфу и обратно (здесь анимация длится 72 кадра - меняя скорость, меняется волнение воды).
- Все, что сделано выше, засовываем в символ и смещаем его по принципу “на половинку с возвратом”. То есть на клипе такой код:
onClipEvent (load) { y0 = _y; y9 = y0 - _height / 2 speed = .5; } onClipEvent (enterFrame) { _y -= speed; if(_y < y9) { var del = Math.abs(_y) - Math.abs(y9); _y = y0 + del - speed; } }
Способ №5. На мой взгляд, обладает большим потенциалом и лучше передает реализм. Как и раньше, единицей воды становится анимированная твиннингом волна. От того, как вы ее закрутите, напрямую зависит результат.
- Рисуем фон и создаем клип воды water - прямоугольник, закрашенный градиентом (к горизонту светлее).
- Создаем клип wave и внутри анимируем волну. Анимация происходит в несколько этапов: вначале гребешок волны поднимается над поверхностью, опускается назад и дальше уже другая форма, деформируясь (анимация отражения по вертикали), смещается вниз с прозрачностью 30% (на глаз). Слева - формы, которые участвуют в анимации. Для них выбран такой же цвет, как у воды над горизонтом. При наложении на градиент появляются блики.
- Ложим клип wave за пределами экрана, а _y выравниваем по горизонту.
Кадром выше пишем код:lev = 0; onEnterFrame = function () { lev++; var d = wave.duplicateMovieClip("w" + lev, lev); d._x = water._x + Math.random() * water._width;//располагаем по горизонту };
Думаю, этих способов хватит на все случаи жизни (мне пока хватало), для игр и баннеров очень даже хорошо подходит. Да и во flash-открытках может пригодиться.
Но не увлекайтесь: анимированное во флэше море - хорошо, а реальное море - лучше!
Интересно на 34%




Последнее море понравилось.
“Но не увлекайтесь: анимированное во флэше море - хорошо, а реальное море - лучше!” // это стопудово
отличные примеры!
Очень классные примеры!
Я хоть сам флешом только увлекаюсь, но этот блог реально самый интересный из всех, что я видел. Каждый пост очень интересный и информативный. Так держать!
Во флэше много вещей, которым я бы хотел научиться, но это - одна из самых полезных тем! И главное, что всё понятно.
Зашел в поисках анимации волны, остался дико доволен результатами
Спасибо громаднейшее
Но у данного способа есть один суровый недостаток — клипы дублируются бесконечно без особых ограничений, что со временем ведет к неизбежным тормозам.
Я сделал немного по-другому: волна генерится с интервалом в 50мс, а при достижении некоего порога (допустим, 300) depth возвращается в исходное состояние. Выходит неплохо - и покрытие в норме, и ресурсы берегутся.
Нету такого недостатка
Когда клип волны доигрывает до конца, он сам себя удаляет, а создавать волны можно, например каждый второй кадр if(lev++%2 == 0){…}
Ну, я, в принципе, догадывался, что так оно и есть на самом деле

Правда в статье об этом практически ничего не говорится.
Может, я что-то просмотрел, или не там читал
Самый верхний пример - 1-й комментарий. Для других примеров я уже не повторял
Значит реально не туда я сморел
Вот сколько раз захожу на этот сайт, столько раз удивляюсь и открываю для себя что-то новое! Все, оказывается, гораздо проще, чем кажется. Спасибо огромное за ресурс!
Спасибо за урок! это еще одна капля в океане изучения флэша
спасибочки,вы мне очнь помогли,разобраться в некоторых хитростях флеша.
Простите. Руки кривые. Все заработало. Спасибо за чудесные уроки
Спасибо большое!
Прям очень в тему мне сейчас!
Привет!
Многоуважаемый Stormit, только начал изучать Flash. вот вроде делаю все как у вас написанно но не получается добится конечного результата. Будте так любезны. Скиньте пожалуйста исходник на мой e-mail ( 3s_wapsmile@mail.ru)
Зарание спасибо!
Пасиба большое за блог!
Возник вопрос, пробую создать волну как в примере №5
но не получается дублирование
1. Создал два клипа фон и фолны.
2. оба клипа перенес в лейер1, клип с волной вынес за пределы картинки но выровнял по горизонту с морем.
3. в леейре 1 в первом кейфреме добаил код.
где может быть ошибка? спс
Ответ на предыдущее сообщение нашел сам, забыл прописать в свойствах имя
У меня не получился первый пример,. Сделал все как надо. Разместил на сцене, у меня wave бесконечно повторяется и все.
Где можно скачать исходник? Или пришлите пожалуйста на discodancer88@bk.ru у кого получилось.
Значит не всё так как надо. Волна не дублируется - почему? Если дублируется и не раскидывается по всей площади - почему?
На эти вопросы можно ответить если проверить переменные функцией trace(). Может переменная lev у вас не изменяется, может клип box отсутствует или не назван. Может ещё что-то.
Очень классный сайт! Столько полезного и интересного можно узнать. И все подробно описано. Спасибо огромное! )
В первом примере волны, гребешки всегда оказываются на переднем плане и перекрывают другие нарисованные объекты, к примеру, корабль. Если ли возможность отправить их на задний план? Подобный вопрос часто возникает при программном размножении объектов.
[…] ЗЫ: в примере тут: http://xitri.com/2008/05/05/more-vod…-ne-tolko.html […]
to Storm
Самый простой способ - положить корабль выше волн (весь клип box) и маской симитировать его погружение в воду.
Видимо, та же проблема, что и у Александра.. волна просто повторяется на одном месте и всё.. создал фон на одном слое, волну на другом.. в символе wave в последнем кадре анимации прописал удаление.. в единственном кадре слоя с волной прописал остальной код..
что-то тоже первый вариант не идет… пришлите пожалуйста исходник vika1533@mail.ru
Сайт классный, очень вдохновляет, но не всегда все получается
Можно я тоже исходник попрошу? Пришлите, пожалуйста, на rondaWh@gmail.com первый и последний примеры.
Дуже тодковий сайт.Я починаю працювати з Flash.
Скиньте будь-ласка файли fla по анімації 1 і 5 прикладу.
на email bo_lu@ukr.net.
Не можу зрозуміти box - це графічний символ чи Movie Clip.
Де ставити на шкалу анімації символ wave, а де box і в яких
кадрах анімації.
Дякую за приклади по анімації води
Спасибо большое за толковые советы, но я как новичок не совсем могу все понять. вот уже на первом примере ничего не выходлит, большая просьба автору - если не трудно, разжевывать побольше материал, а еще лучше выставлять скриншоты монтажной линейки и прочее - чтобы наглядно было видно, куда что “пихать”.
И ссылочку на исходник выложить - было бы обалденно круто. А пока попрошу исходник, как и другие - оч оч надо, пожалуйста!!! iyulka87@yandex.ru
Во флеше недавно,но уже многое получаеться….Хотелось бы сделать этот урок,но блин затрудняюсь,очень…Можно пожалуйста взглянуть на исходник? Спасибо! crumbg@gmail.com