08 марта 2011

Flash: Оживляем фон летающими светлячками

Анимация - это всегда здорово! Бывают игры, полностью построенные на анимации, которые могут затянуть в процесс надолго. Когда что-то движется на экране, оживляя окружение - игрок сильнее погружается в действия, происходящие перед ним. Например, многие были в восторге, когда в Hexen'е над трупом через какое-то время начинали кружить мухи. Пример кровавый и поэтому неудачный, согласен. Сейчас придумаю что-нибудь получше... Вот например Braid полностью пронизан красивыми анимациями: пыль из-под захлопывающейся двери, на фоне падают листья, используется параллакс на движения бэков, при реверсе времени - все эти анимации обращаются вспять и красиво радуют глаз. На самом деле в играх можно найти и взлетающих птиц при приближении игрока, и червяков, изредка высовывающихся из деревьев, и плавную смену времени суток с закрывающимися цветками и начинающимся вечерним ветром, да и многое-многое другое. Игра оживает перед игроком и предстает сочной картинкой, взаимодействующей, а порой просто завораживающей своими анимационными эффектами. Вот и мы немного посмотрим в эту сторону. Сегодня начнем с простого: запустим на фоновое изображение маленьких светлячков, оживляющих картинку своими движениями.
Надеюсь, я еще часто буду обращаться к теме анимации и хитростей, с помощью которых можно разнообразить игру различными эффектами. Поэтому в данном сообщении будет совсем простая вещь: объекты, хаотично движущиеся по экрану. Для меня - это еще одна ступенька для постижения Flash, для журнала - маленькая вкусность, которую он будет хранить в себе, для читателя - возможность найти что-то полезное для себя.
Вот результат, который мы хотим получить:


Просто, но, надеюсь, со вкусом. Определившись с задачей, начнем потихоньку делать нашу flash-ку.
Итак, от слов к делу. Что нам нужно: символ со светлячком. По сути это маленький кружок с эффектом glow. У меня получилось что-то подобное:


Правда glow не очень заметен на скриншоте. Все дело в том, что такое свечение на белом фоне заметить сложно. Но настройки видны - и это замечательно!

Теперь разберем само движение. Оно у нас хаотично, но не полностью. Дело в том, что при таком движении скорость частицы меняется медленно, плавно, изменяя направление полета светлячка не резко, а, наоборот, постепенно. Глядя на результат это очевидно, верно?
Что это нам дает? Во-первых, определяем координаты вектора скорости:

var maxV: Number = 1;
var vx: Number = maxV * Random();
var vy: Number = maxV * Random();

Во-вторых, будем плавно ее менять:

vx = vx + Random() / 5;
vy = vy + Random() / 5;

где я добавил "свой" Random(), который выдает значение от -1 до 1:

function Random(): Number
{
return (Math.random() - 0.5) * 2;
}

Теперь необходимо нормировать вектор скорости, иначе частицы при хаотичном движении могут набрать слишком большую скорость – придется контролировать этот процесс. Например, так:

var sqrL: Number = vx * vx + vy * vy;
if (sqrL > maxV * maxV) {
vx = vx * maxV / Math.sqrt(sqrL);
vy = vy * maxV / Math.sqrt(sqrL);
}

Так, математическая основа готова, теперь нужно начинать творить! Заставим двигаться нашу частицу!
В первом кадре нашего символа-светлячка подписываемся на событие ENTER_FRAME и начинаем «слушать» кадры:

addEventListener(Event.ENTER_FRAME, OnUpdate);

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

if (x < -d) x = dx + x;
if (x > dx) x = x - dx;
if (y < -d) y = dy + y;
if (y > dy) y = y - dy;

где:

var d: int = 10;
var dx: int = parent.width + d;
var dy: int = parent.height + d;

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

Всё... итоговый код для частицы (написан на 1ом кадре):

stop(); var maxV: Number = 1; var vx: Number = maxV * Random(); var vy: Number = maxV * Random(); var d: int = 10; var dx: int = parent.width + d; var dy: int = parent.height + d; cacheAsBitmap = true; addEventListener(Event.ENTER_FRAME, OnUpdate); function OnUpdate(event: Event) { x = x + vx; y = y + vy; vx = vx + Random() / 5; vy = vy + Random() / 5; var sqrL: Number = vx * vx + vy * vy; if (sqrL > maxV * maxV) { vx = vx * maxV / Math.sqrt(sqrL); vy = vy * maxV / Math.sqrt(sqrL); } if (x < -d) x = dx + x; if (x > dx) x = x - dx; if (y < -d) y = dy + y; if (y > dy) y = y - dy; } function Random(): Number { return (Math.random() - 0.5) * 2; }

Осталось только добавить на сцену сотню таких частиц, например, вот таким образом:

for (var i: int = 0; i < 80; i++)
{
obj = new Particle_1();
obj.x = width * Math.random();
obj.y = height * Math.random();
obj.scaleX = 0.5 + Math.random() * 0.5;
obj.scaleY = obj.scaleX;
obj.alpha = 0.7 + Math.random() * 0.3;
addChild(obj)
}


Последняя хитрость: Particle_1 - это символ, внутри которого лежит символ-кружок. Зачем такая сложность? Дело в том, что я не нашел способа наложить glow-эффект на несимволы. Из-за этого приходится кружок-символ класть внутрь другого символа (Particle_1). И уже внутри обертки-символа Particle_1  применять к кружку-символу glow. Вот так - голова кругом...На этом все... кода много, слов мало - наверно все оттого, что и рассказывать-то нечего. Но мне, как новичку во flash - довольно приятно побаловать себя такими анимациями: вроде все просто, а результат симпатичен!

Для придания законченного вида я еще прикрутил простейший site lock, переход по ссылке и "моргающую" надпись. Результат был наверху, с него мы начинали...

Сообщения, схожие по тематике:

3 коммент.:

  1. Выглядит очень здорово. Правильные направления копаешь. :)

    ОтветитьУдалить
  2. что бы не использовать Particle_1 можно попробывать сделать такой финт ушами:
    1.создать объект типа Sprite
    2.в нем нарисовать круг через sprite.graphics.drawCircle
    3.наложить на спрайт фильтр: sprite.filters = [new GlowFilter(цвет, альфа и тд)

    Хотя через Linkage тоже отличный вариант.

    Вот тоже интересная игра не игра построенная на анимации(полный вынос мозга):
    http://flashgameblogs.ru/blog/485.html

    Кстати получился не плохой баннер))))

    ОтветитьУдалить
  3. gltrinix, благодарю! буду стараться))..

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

    не, для баннера нужно что-то посерьезней)).. а здесь просто хотел ссылку попробовать сделать - оказалось, это всего одна строчка)))..

    ОтветитьУдалить