Динамический фон для баннеров и flash-игр

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

Урок от ANIMEFISH.COM

Привет!

Представляю вниманию очередную хитрость для флеш девелоперов - “Создание динамических текстур во флеш”. О чем это я? Частенько в играх, в анимации, существует необходимость использовать качественные текстуры для различных заливок (для фонов, объектов и т.д.) Однако, найти такую текстурку достаточно сложно, подготовить ее к использованию в ролике - тоже сложно (если вы к тому же не владеете растровыми редакторами - это еще проблематичней), импортируемая текстура имеет вес (и не малый) а для вашей игры, например, необходимо много текстур. Но самое важное - это найти ту текстуру, которая бы гармонировала бы с вашей графикой.

Что же делать? Какие пути выхода?

  1. Нарисовать всю картинку целиком - ну тут даже не каждый художник сможет справиться, даже профи :)
  2. Предлагаю воспользоваться моим способом - динамически создавать свою текстуру прямо во Flash!

Начнем.
Суть метода состоит в заполнении ограниченной области различным графическим “мусором”. На 2-м слайде изображены элементы из которых составлен фон на 1-м слайде. Это битмапка для заливки, клип с изображением камня и функция Math.random(). Код примера:

particle._visible = false;
for (z = 0; z < 200; z++) {
	var dupe = particle.duplicateMovieClip("s" + z, z);
	dupe._x = Math.random() * 550;
	dupe._y = Math.random() * 200;
	dupe._xscale = dupe._yscale = Math.random() * 50 + 50;
	dupe._rotation = Math.random() * 360;
	dupe._alpha = Math.random() * 100;
}

Что мы сделали - залили прямоугольную область текстурой травы, а наш камень (клип particle) размножили - разбросали его по всему клипу, изменили ему свойства: вращение, прозрачность, размер.

Теперь усложняем наш фон (слайд 3), добавляем различные варианты “мусора” (в данном случае костяшки и тени). В коде цикла добавляем ещё одну строку, которая переводит символ particleв случайный кадр.

dupe.gotoAndStop(int(Math.random() * dupe._totalframes + 1));

Получаем пример - слайд 4. Такая жуть получилась :)

Ну все это хорошо, скажете вы, но ведь нам все равно нужно некое фоновое заполнение - какая-то текстурка для заливки общего фона. Да, вы правы! В данном примере нужна, а в следующем - нет. Если вы желаете полностью отказаться от чужих растровых заливок - продолжим.

Слайд 5 - создаем “элемент мусора” которым будем заполнять наш фон, его изображение может выглядеть как угодно, главное - цвета подбирать близкие друг к другу, но отличные по тональности (темнее или светлее). Так же можно его размыть (так даже лучше)

Слайд 6 - создаем несколько подобных различных “элементов” и размещаем их в разных кадрах клипа particle. И заполняем наш фон - это первая составляющая будущей текстуры (слайд 7). Слайд 8 - создаем элементы которые составляют второй и третий “этажи” заливки. Для удобства, также поместим их в клип particleв кадры 4, 5 и 6 соответственно. Все эти элементы находятся выше предыдущих элементов составляющих первый “этаж”. На слайде 9 - результат, достаточно миленькая лужайка с ромашками :), код примера:

//трансформация одинакова для всех - выносим в отдельную функцию
function _fill(obj) {
	obj._x = Math.random() * 550;
	obj._y = Math.random() * 200;
	obj._xscale = obj._yscale = Math.random() * 50 + 50;
	obj._rotation = Math.random() * 360;
	obj._alpha = Math.random() * 100;
}
 
// заполняем первый этаж "мусором"
for (z = 1; z < 200; z++) {
	var tmp = particle.duplicateMovieClip("s" + z, z);
	_fill(tmp);
	tmp.gotoAndStop(Math.round(Math.random() * 2) + 1);
}
 
// второй этаж - травой
for (z = 201; z < 400; z++) {
	var tmp = particle.duplicateMovieClip("s" + z, z);
	_fill(tmp);
	tmp.gotoAndStop(Math.round(Math.random() * 2) + 4);
}
 
// третий этаж ромашками
for (z = 401; z < 500; z++) {
	var tmp = particle.duplicateMovieClip("s" + z, z);
	_fill(tmp);
	tmp.gotoAndStop(6);
}

Все прекрасно, все красиво, а тормоза? Все теперь это будет тормозить наш ролик! О нет! Хотя, есть же прекрасный пример с растеризацией вектора. Применим его к нашей картинке (для этого пришлось символ particle, обернуть в символ bg). В этом случае код выглядит так:

function _fill(obj) {
	obj._x = Math.random() * 550;
	obj._y = Math.random() * 200;
	obj._xscale = obj._yscale = Math.random() * 50 + 50;
	obj._rotation = Math.random() * 360;
	obj._alpha = Math.random() * 100;
}
 
// заполняем первый этаж "мусором"
for (z = 1; z < 200; z++) {
	var tmp = bg.particle.duplicateMovieClip("s" + z, z);
	_fill(tmp);
	tmp.gotoAndStop(Math.round(Math.random() * 2) + 1);
}
 
// второй этаж - травой
for (z = 201; z < 400; z++) {
	var tmp = bg.particle.duplicateMovieClip("s" + z, z);
	_fill(tmp);
	tmp.gotoAndStop(Math.round(Math.random() * 2) + 4);
}
 
// третий этаж ромашками
for (z = 401; z < 500; z++) {
	var tmp = bg.particle.duplicateMovieClip("s" + z, z);
	_fill(tmp);
	tmp.gotoAndStop(6);
}
 
var tmp_bitmap = new flash.display.BitmapData(550, 200, false, 0x00000000);
bg_rastr1 = this.createEmptyMovieClip("bg2", 10000);
bg_rastr2 = this.createEmptyMovieClip("bg3", 10001);
 
tmp_bitmap.draw(bg);
bg_rastr1.attachBitmap(tmp_bitmap,10002);
bg_rastr2.attachBitmap(tmp_bitmap,1003);
bg_rastr2._xscale = 400;
bg_rastr2._yscale = 400;
 
//маскируем увеличенную копию
bg_rastr2.setMask(this._mask);
 
//И удаляем оригинал с векторным изображением нашего фона
bg.swapDepths(10004);
bg.removeMovieClip();

Где tmp_bitmap временный клип в который мы производим конвертацию bg_rastr1 и bg_rastr2 - динамически созданные клипы которые будут содержать наше растрировнное изображение. bg_rastr1 - основной клип, а bg_rastr2 - не обязательный, создан для наглядности (его мы увеличим в 4 раза (400%) и закинем под маску _mask).

Дальшея думаю понятно, _mask - клип нашей маски который содержит скрипт

onClipEvent(enterFrame){
	_x=_parent._xmouse;
	_y=_parent._ymouse;
}

Все - слайд 10, показывает результат нашей деятельности.

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

На этом все, спасибо за внимание, ваш animefish.

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

(53) Хитрых на тему «Динамический фон для баннеров и flash-игр»

  1. TRY

    Офигенно! Спасибо за ценную хитрость!

  2. Bulat

    Прикольно нарисованно, хороший урок
    А еще это можно использовать в будущем уроке про подвижный фон)

  3. Саша

    О да! Блог снова ожил!

  4. Platon

    Для тех, кто использует не AS2, а AS3, для концертации в растр нужно вместо строк

    //as2 sample
    var tmp_bitmap = new flash.display.BitmapData(550, 200, false, 0×00000000);
    bg_rastr1 = this.createEmptyMovieClip(”bg2″, 10000);

    tmp_bitmap.draw(bg);
    bg_rastr1.attachBitmap(tmp_bitmap,10002);
    //

    использовать следующие:
    //as3 sample
    var tmp_bitmap = new flash.display.BitmapData(550, 400, false, 0×00000000);
    tmp_bitmap.draw(bg);
    var bm:Bitmap = new Bitmap(tmp_bitmap);
    addChild(bm);
    //

    так же при удалении нужно удалить всех чайлдов мувика bg и ссылки на них.

  5. Platon

    Извините, ошибся в строчке
    var tmp_bitmap = new flash.display.BitmapData(550, 400, false, 0×00000000);
    - должно быть не 400, а 200.

    Впрочем, если кому интересно, могу выложить полный as3 код.

  6. dedsky

    To: Platon
    Если можно, выложите весь AS3.

  7. buagaga

    статья - суперская !

  8. Саша

    А возможно ли таким способом нарисовать, например, звёздное небо?

  9. animefish

    Саша - можно и звездное небо. Все что ваша фантазия пожелает - рисуйте вместо камешка звездочку + синий фон и вуаля!

  10. Platon

    исходник на as3 + фильтр blur и смена картинки по клику.
    http://narod.ru/disk/10292096000/dynafone.rar.html

  11. Сталекс

    Интересно на 25%
    Спасибо!

  12. SARFEX

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

  13. Bulat

    Драсте а когда будет урок про подвижный фон?

  14. SARFEX

    Stormit хотим ещё уроков!!))
    Лично меня очень интересуют вопросы оптимизации
    Например вот тема - Оптимизация карты для игры - в котором описывается то что в играх, где есть большая карта и привязанный к камере персонаж, нужно использовать предзагрузку только той части где этот персонаж находится. Чем не хитрёж?)

  15. Stormit
  16. Argentum

    Ребята, извините за оффтоп, очень понравился ваш подход, подскажите литературу для начинающего работать с флэш. Буду рад советам, с чего начать и какими программами пользоваться. Опыт в программировании минимальный.
    Заранее большое спасибо.

  17. Саша

    Argentum, поищи учебник Гурского. Еще есть небольшая, но классная книга MyFirstGame Johnny.K

  18. SARFEX

    2Stormit
    Да это понятно, интереснее реализация. Например как сделать методом выше (+растр) чтобы например при движении “камеры” вправо (mc с фоном влево) чтобы “на лету” генерился такой же рандомный динамичный битмап. При этом возможно будут заметны швы… Я вот не знаю)

  19. Bulat

    http://xitri.com/2008/05/20/flash-effects-animation-tutorials.html
    вот тут почемуто не рабочие ссылки на уроки :( можете дать другие уроки(ссылку и тд) :(
    Извините за оффтоп

  20. SARFEX

    http://www.floobynooby.com/FXmontage2.mov
    это видео, нужно скачать

  21. pacific

    Здравствуйте!!! Я начинающий разработчик. Мне хочется сделать гонки. Пожалуйста напишите урок как разработать противников. Заранее спасибо!!!

  22. animefish

    Bulat, студия которая размещала на своем блоге материалы о спецэффектах - закрылась (coolideascope), Все материалы по эффектам (и несколько новых) тут http://flashfx.blogspot.com/

  23. Stormit

    >>чтобы “на лету” генерился такой же рандомный динамичный…
    Можно так: http://xitri.com/2008/04/21/loop-background2.html
    Можно проще: создать один объект BitmapData с начальным фоном и при движении камеры шлёпать справа или слева новые элементы фона рандомно. Если картинка становится большой - обрезать её. Как вариант.

  24. Stormit

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

  25. pacific

    Спасибо!!!!!!

  26. SARFEX

    >> Можно проще: создать один объект BitmapData с начальным фоном и при движении камеры шлёпать справа или слева новые элементы фона рандомно. Если картинка становится большой - обрезать её. Как вариант.

    Ну я так и думал, только не могу что-то это реализовать.
    Имеем bg. в нём созданный bgrastr. bg статичен. _root двигается по _x и _y
    Не подскажете как это можно сделать? Как доделаю сайт обязательно будет ссылка к вам :)

  27. Bulat

    animefish большое спасибо

  28. Vishd

    Замечательно! Дизайн и идеи - все супер. Акромя AS2.
    Stormit, ты не только можешь, но и должен расти! (с таким то потенциалом)

  29. animefish

    pacific - может вам стоит начать как и все, с элементарного, изучить базовые понятия флеша, а не делать сразу игру. По сути игра - это логическая машина которую автор создает, а реализована эта машина может быть на любом языке. Если вы не знакомы ни с принципом создания игры, ни с средой программирования - вам будет тяжело.

  30. Ni 4 Go

    thanks))
    awesome article!

  31. SARFEX

    Stormit не поможете да?(
    Как определить когда загружать продолжение фона знаю, а как продолжать рисовать фон с методом выше (+перегонка в растр) не знаю. Heeeelp)

  32. Stormit

    Немного другим способом можно.
    Создаём BitmapData (дальше BD) для фоновой картинки (например в 3 раза шире флешки), аттачим к клипу (который будет содержать фон). Центрируем BD относительно флешки чтобы были выступы по бокам. Теперь заливаем центральную часть BD (та что видна в данный момент) фоном. При движении персонажа вправо/влево, фон движется и мы заполняем пустую часть рисунком. Когда BD двигаться уже некуда, переносим видимую часть фона в начало или конец BD (смотря в какую сторону двигались), а саму BD смещаем на такое же расстояние в другую сторону.
    Надеюсь разберётесь, хотя это довольно сложно, гораздо проще сделать безшовную текстуру. Задача как раз пойти по пути наименьшего сопротивления.

  33. DarkSnow

    Супер! У меня тут затруднения возникли, фон 3000х4500 пикселей
    если создавать 13-15 тыс объектов, то это все очень долго загружается да и выглядит как-то плохо…
    с 1300 на 300х450 все выглядит супер, но мне нужно 3000х4500, как это сделать?
    дублирование растра ничего не дало…

  34. animefish

    DarkSnow - ого! такой большой фон :) Могу предложить объединить объекты в “группы”, то есть уже заранее сделать группу скажем цветов - 300 на 450 и ее разбрасывать - тогда можно снизить число объектов с 13000 скажем до 1300.

  35. DarkSnow

    animefish
    а это идея кстати спасибо!а прогрмано можно как-нибудь объединять в группы?
    З.Ы. а вы для vkontakte приложение не пишите?там прост раскручивать их несложо, да и апи легко выучить

  36. dedpbIxto

    DarkSnow - можно программно объединять в группы, нужно создать новый клип (программно) и в нем создать фрагмент, потом уже этот клип размножить.Вконтакте - да работаю в этом направлении :)

  37. Potapof

    Спасибо, очень интересный блог. Много полезных хитростей.

  38. saintist

    Очень все хороше здесь )), понравилось, вам пора на AS3 переходить

  39. dedpbIxto

    Переходим :)

  40. Creator

    Неплохо, даже здорово. Жаль что duplicateMovieClip, не работает с loadmove а так бы можно было бы генерить различных фон не прошитый в основном ролике.

  41. Возвращение. Wacom. « Murlyka Studio

    […] Хitri рассказал про скроллинг, динамические фоны и простой движок для флеш […]

  42. RussiaWithGod

    Очень интересно, и довольно просто, спасибо за ценный совет!=)

  43. man_old

    Спасибо. И мне пригодилось и студенты порадовались :-). Хороший урок. Правда с растеризацией не все получилось

  44. Gregor

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

  45. Sergix

    Не подскажете как сделать что бы они не залазали друг на друга, а ещё лучше были впритык друг к другу?

  46. Sergix

    Сделал очень грубый вариант… И не знаю как теперь к этому растеризацией вектора применить. Или лучше поменять код? Вот собственно он.
    onEnterFrame = function () {
    amount = 85;
    a = 10
    k = 0
    i = 0;
    f = 0;
    g = 0;
    while (a>0) {
    while(amount>0) {
    duplicateMovieClip (_root.particle, “mc” + i +g, i);
    setProperty(”mc” + i, _x, f++ * 5);
    setProperty(”mc” + i, _y, k);
    i = i + 1;
    amount = amount-1;

    }
    amount = 85;
    g = g+1;
    a = a-1;
    k = k+19;
    f=0;
    }
    }
    думаю что можно в 100 раз легче сделать, но что то не что в голову не лезет.

  47. sergei

    ну я немного по-другому делал фон, но этот способ надо будет попробовать тоже

  48. Sergix

    Простите что не отписался. Уже всё сделал в этом плане.

  49. SporeS

    Сайт - супер смотрю и нарадоваться не могу, но вот только с этим фоном - запара… как бы сделать чтоб он имено “фоном” был? а то я сдалал, вставляю и получается что “фон” поверх всего остального… я лох или тормоз? :)

  50. Stormit

    Программно созданные клипы помещаются на самый верхний слой текущего клипа (сцены. если в _root) - это нормально. Чтобы фон был ниже объектов, создайте для него отдельный клип и все объекты плодите внутри него. Теперь этот клип с фоном можно во флеше поместить на любой слой.

  51. SporeS

    для Stormit:
    Огромное спс)

  52. Антон

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

  53. Vasyka

    Ничего не получилось, у меня получилась просто анимация из 5-ти разных объектов

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