Циклическая анимация фона - Часть первая

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

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

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

Сама циклическая анимация создается по принципу “бесшовных текстур”. Края фонового изображения при стыковке должны создавать неразрывную картинку.

Самый простой способ - сделать все твиннингом. Но при этом теряется контроль над скоростью анимации (доступны только stop() и play() ). Если персонаж обладает ускорением, нестыковки с фоном будут обязательно.

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

  1. Рисуем фон.
  2. Растягиваем его по размерам будущей флэшки, даже чуть больше. Если есть выступающие элементы, их нужно отрезать с одной стороны и перенести в другую (я так поступил с тенью от забора).
  3. Оборачиваем все это в клип, дублируем и переносим дубликат точно в конец оригинала. Это важно, иначе фон при анимации может дергаться. Кстати сейчас очень удобно доработать “бесшовность” - линии между клипами должны соединяться без изломов. Выделяем оба клипа и оборачиваем их в еще один клип.
  4. На этом символе пишем код:
    onClipEvent (load) {
    	speed = 4;//скорость
    	x0 = _x;//Запоминаем начальное положение
    	x9 = x0 - _width / 2;//максимально-допустимое левое положение
    	onEnterFrame = function() {
    		_x -= speed;
    		var dx = x9 - _x; //Вычисляем перебор
    		if (dx > 0) {
    			_x = x0 - dx;//Компенсируем его и возвращаем в начальное положение
    		}
    	}
    }

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

  5. Получаем зацикленную анимацию.
  6. Вот так, если добавить окружение и действующее лицо.
  7. Или вот так.
  8. Или так.

Анимация сейчас привязана к переменной speed, которую можно менять по обстоятельствам.

Кому интересно, дальше о том, как анимируется мяч:

ball_animation

Многое из картинки должно быть понятным. Имеем символ мяча и вся эта анимация происходит внутри него. В последнем кадре скрипт отрабатывает плавность анимации (чтобы не было 2-х одинаковых положений подряд). Скрипт вращения мяча пишется не на клипе который смещается твиннингом, а на другом клипе внутри него. Тоесть всего имеем: клип мяч -> мяч1(нарисован на картинке) -> мяч2 - вот на нем и пишем. Клипы, которые участвуют в твиннинге, программно смещать нельзя, иначе пропадает сам твиннинг.

Все это происходит внутри клипа мяч. Чтобы он двигался за мышкой, на нем пишем код:

onClipEvent (load) {
	backSpeed = 4;//то же что и speed у фона
	maxSpeed = 5;//будем ограничивать максимальную скорость
	speedX = 0;
	onEnterFrame = function() {
		var dx = _parent._xmouse - _x;
		speedX += dx * .1;//сила притяжения к курсору
		speedX *= .7;//затухание
		speedX = (speedX > maxSpeed)? maxSpeed : (speedX < -maxSpeed)? -maxSpeed : speedX;
		if(_currentframe < 23) {
			_x += speedX;//если в воздухе
		} else {
			_x -= backSpeed;//если прижаты к земле
		}
	}
}

Здесь реализовано движение “пружинкой” (переменная _x изменяется не напрямую, а через переменную скорости - speedX, к которой предварительно прикладываются сила натяжения и затухание). Оно достаточно гладкое, управляемое подходит для этого случая. Если мяч касается земли (кадры 23-31), то действует сила трения и он в этот момент “привязан” к фону. По правильному, переменная backSpeed у мяча и speed у фона - одно и тоже. Здесь я их разнес чтобы сделать код независимым.

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

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

(12) Хитрых на тему «Циклическая анимация фона - Часть первая»

  1. Mastak

    У меня лично ругается на устаревший оператор “gt”.
    в первом коде 9 строка - “if (dx>0) {”. С ней все работает.

    Огромное спасибо за отличную тематику сайта! Первый раз такое встретил на просторах рунета, а то кругом одни скучные программисты с блоками о программинге. Бедному аниматору и приткнуться некуда:) Так держать! Читаю от кроки до корки, все очень интересно и нужно нашему брату!:)

  2. Stormit

    Блин, это наверное Wordpress подменил. Я таким вообще не пользуюсь. Сейчас поправлю

  3. Котов

    Есть небольшое примечание к анимации. Мячик в состоянии сплющивания, т.е. когда он на земле, движется медленнее чем когда он в воздухе. Из-за єтого кажется что он живой, а не прыгает по инерции) Такое торможение я думаю будет уместно применить скажем в анимации Колоба, или другого туловищеголового персонажа, который перемещается путем прыганья) А чтоб создалось впечатление свободного, динамичного прыганья скорость должна быть и вверху и внизу одинаковой.

  4. Stormit

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

  5. Котов

    Бла-бла-бла. Вот мне например, сразу бросилось в глаза. Послушай художника, дизайнер :)

  6. Mastak

    2Котов:
    Как по мне, тоже подправил бы анимацию мячика, но наверное к этому придираться не стоит, главное автор задал вектор, а как кому нравится - это уж дело вкуса. Правьте анимацию на свое усмотрение, какие проблемы?

  7. nouba

    onClipEvent (load) { - очень, ну очень, плохая практика =)

  8. Владимир

    Привет

    Хотельсь бы ещё увидеть исходники на AS2 и AS3.
    Это бы мне очень помогло.

    Заранее спасибо

    Владимир

  9. ded pb|xto

    nouba, А чем плоха? Малой ведь кровью… Тем более что метод применим и к старым версиям флеша.

  10. Stormit

    ded pb|xto прав. Смысл в том чтобы упростить.
    В сложных скриптах здесь нет необходимости. Это чаще используется для игровых баннеров, а там просят FlashPlayer 6.
    А на классах сделать не сложно - пусть конструктор принимает мувик фона в качестве параметра. Задаем скорость через сеттер (или ссылаемся на общую для всей флэшки), а какая-нить функция step() будет смещать фон на величину скорости (со всеми проверками).

  11. Lerika

    обжал ;)

  12. alexey

    большое спасибо автору за эту статью. очень меня выручила в нужный момент.спасибо!

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