PDA

Просмотр полной версии : timer для анимации


flax4Noob
07.01.2011, 14:13
на сцене есть кучка спрафтов. Каждый из них необходимо анимировать (вращать) скорость задается некой переменной внутри спрайта. и каждому я припаял функция "onAnimate", которая его поворачивает. Так вот, теперь вопрос:

Что лучше сделать: один таймер в контроллере, который будет по массиву спрайтов вызывать эту функцию, или создать каждому объекту персональный таймер с персональным обработчиком? Или может можно прилепить одному таймеру все эти обработчики?) Или как вообще делают взрослые дяди?

ЗЫ во флеше 7й день. не пиннать :Р Ушел гуглить дальше.

samana
07.01.2011, 14:25
Я думаю первый вариант лучше всего.
один таймер в контроллере, который будет по массиву спрайтов вызывать эту функцию

flax4Noob
07.01.2011, 15:37
а не получится ли из-за этого задержки с выполнением анимации между первым и последним элементами? Возрастающей по мере увеличения массива.. оО

samana
07.01.2011, 15:59
Между объектами задержек не будет, они будут работать синхронно, либо тормозить синхронно, если массив например будет очень большим. Рендеринг сцены происходит после выполнения всего кода, а не по мере его чтения.

mikhailk
07.01.2011, 19:41
Правильное решение, на мой взгляд, такое:
1. Крутить всех вместе по единому таймеру (вызывать функцию в каждом из объектов)
2. Внутри каждого объекта учитывать возможные временные задержки, т.е., при вызове функции вращения поворачивать не на фиксированный угол, а на угол, пропорциональный времени, прошедшему с момента последнего вызова.

Собственно, это (пункт 2) стандартное решение для флеша.

flax4Noob
07.01.2011, 19:55
а где-нить можно взять "стандартный для флеша" пример? Что-то мне не очень хочется косячить, ваяя собственные класы для типовых задач. Наверняка где-то есть готовый класс с анимацией по "тикам", хранением последнего вызова, усреднением кадра и проч.. и для мувиков тоже не плохо было бы увидеть

mikhailk
07.01.2011, 20:54
Я думаю, в TweenLite/TweenMax эти вопросы решены.

Но применительно к рассматриваемой задаче я не вижу возможности где-то накосячить. Cейчас у Вас там что-то типа:


private var dRotation:Number = 10;
private var timerInterval:int = 200;
private var timer:Timer = new Timer(timerInterval);

private function init() : void
{
timer.addEventListener(TimerEvent.TIMER,onTimer);
timer.start();
}

private function onTimer(e:Event) : void
{
// mcArray - массив вращаемых объектов
for(var i:int=0;i<mcArray.length;i++) mcArray[i].rotation += dRotation;
}



а после ввода коррекции будет примерно так:



private var dRotation:Number = 10;
private var timerInterval:int = 200;
private var timer:Timer = new Timer(timerInterval);
private var currentTimer:int;

private function init() : void
{
timer.addEventListener(TimerEvent.TIMER,onTimer);
currentTimer = getTimer();
timer.start();
}

private function onTimer(e:Event) : void
{
var dRotationCorrected:Number = dRotation * (getTimer()-currentTimer) / timerInterval;

// mcArray - массив вращаемых объектов
for(var i:int=0;i<mcArray.length;i++) mcArray[i].rotation += dRotationCorrected;

currentTimer = getTimer();
}


Как-то так.

Psycho Tiger
07.01.2011, 21:24
99% всех анимаций должны обновляться каждый кадр, отчего таймеру выбирают значение 1000 / stage.fps.

Если это Ваш случай, то поделитесь пожалуйста соображениями, при которых Вы используете таймер ENTER_FRAME эвенту.

flax4Noob
07.01.2011, 22:32
99% всех анимаций должны обновляться каждый кадр
У меня после 7 дней изучения флеша остались сомнения по поводу вызова события ENTER_FRAME для шейпа, который сейчас скрыт за пределами сцены, но это не значит что он должен прекратить вращаться... это будет несколько неестественно.
Кроме того, я планирую использовать этот Аниматор для проигрывания произвольных мувиков, подгружаемых на сцену по мере необходимости слегка корректируя их скорость методами gotoAndStop или как там... забыл(

Psycho Tiger
07.01.2011, 23:38
Любой DisplayObject получает событие ENTER_FRAME всё время своего существования в памяти.

flax4Noob
08.01.2011, 00:20
На самом деле пример mikhailk вполне рабочий, только не учитывает остаток от деления, что может создать некие рывки в анимации. Пойду разгугливать TweenLite etc. Не всегда анимация нужна для потомка DisplayObject. хочется общего решения. Буду кавырять. Пасипа.

Psycho Tiger
08.01.2011, 00:40
Ничто не мешает получить событие ENTER_FRAME непотомку DisplayObject от потомка.

flax4Noob
08.01.2011, 00:57
та я не спорю, что ENTER_FRAME это хороший способ. Просто в любом случае, не зависимо от источника события, необходимо подсчитывать время с момента прошлого "тика", считать кадры которые прошли за это время и отрисовывать уже последний из них. Чем может быть вызван прокуск событий я не могу сказать во флеше. Но в других ЯП под виндой это было банальное таскание окошка по экрану. После которого вся сцена "прыгала" на нужное время пропуская по 40-50 кадров).

ЗЫ поспамил на ютубе правой кнопкой по ролику-ролик прыгает на нужные кадры, пропуская те что не влезают в тайминг. Может во флеше это уже как-то реализовано и я чешу спину пяткой? оО

Psycho Tiger
08.01.2011, 13:23
ENTER_FRAME, а время высчитывается, например, через getTimer. В итоге обновляем экран каждый кадр, но время смотрим которое действительно прошло, т.е. дельту - getTimer() - oldGetTimer.