Гори, гори ясно, чтобы не погасло - программный огонь во флэше

12.05.2008, автор Stormit, рубрики: ActionScript, Flash игры, Игровые баннеры

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

Сделать огонь проще, чем это может показаться. Ничего военного в этом нет. Хитрость в том, как его потом можно использовать. Посмотрите на примеры ниже: из пламени полученного в первом кадре остальные эффекты получаются за несколько минут (рисование я не считаю).

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

Собственно, как это сделать:

  1. Создаем символ part с круглым градиентом желтого цвета, уходящего в прозрачность.
  2. Оборачиваем его в новый символ fire и внутри делаем анимацию как на примере. Не секрет, что самая горячая точка - самая яркая, а чем дальше от нее, тем цвет темнее (в жизни еще и оттенок меняет). Я использовал градацию от желтого к красному. К тому же, в середине анимации символ part наиболее большой по размерам и имеет оранжевый оттенок. Изменение цвета производится применением эффекта Tint (100%). Таким образом, если градиент переходит в прозрачность, символ part просто поменяет цвет. К концу анимации цвет пламени становится красным, а прозрачность сходит на нет (на примере прозрачность не показана, но она должна быть). Самый простой способ - вначале затинтовать символ красным, а затем изменить эффект на Advanced и опустить альфу до нуля. Когда частица отыграла свое, она удаляет сама себя. Для этого в последнем кадре пишется:
    this.removeMovieClip();
  3. На той же линейке, где лежит символ fire, слоем выше на кадре пишем код:
    fire._visible = false;//скрываем эталон
    lev = 0;//переменная для уровней
    this.onEnterFrame = function() {
        for (var i = 0; i < 2; i++) {//выполняется 2 раза чтобы увеличить плотность
            lev++;
            d = fire.duplicateMovieClip("f" + lev, lev);
            d._x += Math.random() * 6 - 3;//случайный разброс по координатам
            d._y += Math.random() * 6 - 3;
            d._alpha = Math.random() * 50 + 50;//реализм
            d._xscale = d._yscale = Math.random() * 50 + 70;//реализм
        }
    }
  4. Вот таким или примерно таким должен быть результат. Все что получилось оборачиваем в новый символ. Теперь у нас в руках мобильный огонь, который можно смещать, поворачивать, масштабировать, дублировать и т.д.

Пламя есть, осталось придумать что поджигать. Возвращаясь к первой флэшке с примерами, огненное кольцо сделано из 6 огоньков накиданных сверху по периметру, а огонь у ракет - поворотом на 90 градусов. Горящий БТР - все то же самое, но в символе part вместо векторного градиента используется растровая картинка (дым).
Отдельно остановлюсь на примере с горящей бомбой. Отличается от остальных, верно? Так и есть, код для шага 3 немного другой:

fire._visible = false;
lev = 0;
this.onEnterFrame = function() {
    for (var i = 0; i < 2; i++) {
        lev++;
        if(lev > 1000) {
            lev = 0;
        }
        d = fire.duplicateMovieClip("f" + lev, lev + 2000);//огонь
        d2 = fire.duplicateMovieClip("f2" + lev, lev);//контурная подложка
        d2._x = d._x += Math.random() * 6 - 3;
        d2._y = d._y += Math.random() * 6 - 3;
        d._alpha = Math.random() * 50 + 50;
        d2._xscale = d2._yscale = d._xscale = d._yscale = Math.random() * 50 + 70;
        var col = new Color(d2);
        var tr = col.getTransform();
        tr.ab = tr.rb = tr.gb = tg.bb = 255;//не знаю почему, но закрашивает желтым
        col.setTransform(tr);
    }
}

В этом случае частиц создается в 2 раза больше - одна половина, как и раньше, составляет огонь (уровень 2000-3000), а другая - желтую подложку с резким контуром (уровень 0-1000). Уровни не перекрываются.
Кстати, разбираясь в своем старом примере, не смог въехать, почему подложка закрашивается желтым, а не белым цветом. Ведь по логике параметры поднимаются одинаково и если задать руками, получится белый цвет. Баг?

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

  1. Убираем анимацию движения языка пламени вверх - получается интересный эффект (почти как инферно в Героях).
  2. Но для интерактивности нужен только символ fire. Символ part в первом кадре анимации я сделал крупнее.
  3. Есть функция, которая создает дубликат огонька и располагает его по заданных координатам (огонек проигрывает анимацию и потом удаляет сам себя). Теперь на событие enterFrame дубликат огонька привязывается к мышке (можно поводить ею по флэшке):
    fire._visible = false;
    lev = 0;
    function placeFire(x, y) {
        for (var i = 0; i < 2; i++) {
            lev++;
            d = fire.duplicateMovieClip("f" + lev, lev);
            d._x = x + Math.random() * 6 - 3;
            d._y = y + Math.random() * 6 - 3;
            d._alpha = Math.random() * 50 + 50;
            d._xscale = d._yscale = Math.random() * 50 + 70;
        }
    }
    onEnterFrame = function() {
        placeFire(_xmouse, _ymouse);
    }
  4. Более практичный случай.
    Огоньки привязываются к шару, который двигается программно. Получается мячик из Арканоида во взрывном режиме.

Но не стоит злоупотреблять такими эффектами. Сцена с 2-3 такими огнями может подтормаживать (делайте поправку на крутые компы). Скорее это подходит, чтобы лучше выделить объект из фона - сделать на нем акцент. Если же есть необходимость в большом количестве, старайтесь уменьшать их размеры - будет перерисовываться меньшая площадь.

Интересно на 47%

(41) Хитрых на тему «Гори, гори ясно, чтобы не погасло - программный огонь во флэше»

  1. shoosh

    Красота! )

  2. Ди.

    Спасибо, очень приятно читать и видеть все посты

  3. Lerika

    супер-мега респект! у мы уже даже придумали как этот код оптимизировать )

  4. Stormit

    Я тоже придумал :) А вообще наверное любой код можно оптимизировать (и так много раз).

  5. Mastak

    “мы уже даже придумали как этот код оптимизировать”

    Lerika, а почему не делимся со всеми?;) Код в студию!:)

  6. Ant

    +1, мега практичный хитрик

  7. Ant

    и никаких битмапов,фильтров!

  8. Stormit

    Ну, там где БТР горит, битмап есть :)

  9. motor

    Сайт просто супер! Продолжайте в том же духе. Был бы очень признателен, если бы посоветовали с чего начать изучение Флеша и Экшен Скрипта, возможно какую-нибудь книгу хорошую. Заранее спасибо.

  10. PITon

    Замечательная статья! Мне почему-то сразу захотелось сделать огонь и автомата :-)

  11. reventon

    бум пробовать!

  12. antory

    у меня, почему-то “&lt” и “&gt” не работает. заменил на “1000″, тогда тоже заработало. а иначе выдает ошибку “unexpected encountered”. почему так? as2, flash cs3

  13. Stormit

    Это глюк движка, который меня больше всего раздражает.
    Постоянно заменяет символы “< " и ">” на “&lt” и “&gt”.
    Наверное после восстановления базы опять переписал.

  14. antory

    уфф! уфф! я уже в хелпе почти нашел их, потом сообразил, что в конструкции for лишний параметр =) оказывается, все не так страшно. но, тем не менее, урок очень хороший. большое спасибо!

  15. DELer

    использовал твой огонь самым беспардонным образом http://www.deler.ru/b/Rich/Rich-media35.htm
    надеюсь, не проклянешь? ))

  16. Sergey

    клева
    автор молодца

  17. dil okullari

    do you know any information about this subject in other languages?

  18. Stormit

    Sorry, but my English is not so strong to write on it. May be in future.

  19. antory

    товарисч, кажется, хочет прочитать об этом на инглише или на other languages. могу посильно помочь, если нужно

  20. Stormit

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

  21. antory

    да, это понятно =)
    но если у меня, вдруг, появится дикое альтруистическое желание, перевести одну (или больше) твоих статей, надеюсь, ты не будешь сильно злиться по этому поводу? =)

  22. Stormit

    Только если с прямой ссылкой на оригинал и то, в пределах разумного.
    Английский клон моего сайта делать нельзя =)

  23. antory

    Клон, я, конечно-же, делать не собираюсь. мне бы со своим разобраться =)

  24. Глеб

    Отлично!. Все-таки, для того, чтобы вести по-настоящему интересный блог нужно не только просто постить в него о чем-то, но и делать это выкладываясь

  25. kokc

    ннннн-да.друзья,вот вам площадочка детская-[клик по ссылку], можт кто захочт помочь оптимизировать,я на флэш ужо торкнутый,тока ни-бум-бум не въезжаю,а сайтик реально мой, хочтса чоб красиво,пробувал всяки исходники пытать-мало что получатся,да и опыту маловато,обещаю всем на спецвкладочке ссылочку и респект.

  26. nadezda_klepa

    Все получилось в точности как на примере! Огромное спасибо за пошаговое разъяснение! Респект! ))

  27. Белыч

    Очень интересный сайт, большое спасибо автору) Всегда приятно что то сделать самому и потом любоваться) Мой огонек, твоя заслуга=)

  28. Вика

    Полезный пост. Натыкался на сообщение, что в скором времени будет конкурс блогов. Почитываю ваши посты и есть мысль, что вам следует поучаствовать. Кто знает, во что выльется?

  29. Stormit

    Я думаю эти конкурсы постоянно кем-то проводятся на разные темы и в разных масштабах, но я бы с удовольствием поучаствовал :)

  30. Kerby Look

    Хорошо. Только почему огонь получается, как будто резкость не наведена?

  31. insurance young driver

    Спасибо, хорошая статья. Подписался.

  32. Hagemay

    Красивооооо…. Респект тебе аффтар =)

  33. muguninimua

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

  34. Stormit

    Удачи ;)

  35. Lil RoM

    Супер!

  36. SKS

    А у меня не получается :( На 3-ем шаге ничего не происходит. Не понимаю в чем проблема. Так хочется нарисовать бомбу… эээх

  37. Stormit

    Может символ с огнём не назван?
    Протрэйсируй все переменные - где данные теряются?

  38. Дига

    Ребят, я тока недавно начал изучать флеш и поэтому как чайник хочу спросить: “Оборачиваем его в новый символ fire и внутри делаем анимацию как на примере”, это как?
    Если не затруднит, обьясните подробнее.

  39. Stormit

    Это значит - F8 (Create Movie Clip), называем его fire, а внутри него делаем анимацию.

  40. Дига

    Спасибо, первую, графическую часть я осилил)), а вот по поводу скрипта, на последнем, 30 кадре, я нажав на action написал this.removeMovieClip(); на что после проигрывания клипа программа написала:
    TypeError: Error #1006: removeMovieClip is not a function.
    at my_fire_digger_fla::fire_1/my_fire_digger_fla::frame30()
    что сие значит. Заранее спасибо.
    PS. надеюсь не замучал распросами, просто очень хочеться влиться в сообщество флешеров, очень мне возможности flash и action script понравилися)

  41. Дига

    Ребята, скиньте мне кто-нибудь исходник огня в flash, у кого получилось, у меня почему-то не пашет, пожалуйста)
    адресс: sergey_digger@mail.ru

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