Это плохая идея для реализации цикла таймера во Flex? - PullRequest
3 голосов
/ 24 сентября 2008

В нашем игровом проекте у нас был цикл таймера, настроенный на срабатывание примерно 20 раз в секунду (так же, как частота кадров приложения). Мы используем это для перемещения некоторых спрайтов. Мне интересно, может ли это вызвать проблемы, и мы должны вместо этого делать наши обновления, используя обработчик события EnterFrame? У меня складывается впечатление, что выполнение цикла таймера быстрее, чем частота кадров приложения, может вызвать проблемы ... так ли это?

Как обновление, попытка сделать это на EnterFrame вызвала очень странные проблемы. Вместо кадра каждые 75 мс вдруг он прыгнул до 25 мс. Обратите внимание, что это был не только наш расчет , заявленный частота кадров была другой, внезапно анимация ускорилась до безумной скорости.

Ответы [ 5 ]

4 голосов
/ 25 сентября 2008

Вот краткое изложение того, как Flash обрабатывает частоту кадров и почему вы видели, как ваш контент воспроизводится быстрее.

На самом глубоком уровне, любое хост-приложение, в котором работает Flash (обычно браузер), опрашивает вспышку через некоторый интервал. Этот интервал может быть каждые 10 мс в одном браузере или 50 мс в другом. Каждый раз, когда происходит этот опрос, Flash делает что-то вроде этого:

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

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

Обратите внимание, что асинхронное поведение этих событий не влияет на время обновления кадра. Даже если вы используете события таймера, например, для перерисовки экрана 50 раз в секунду, анимация кадров будет по-прежнему происходить при опубликованной частоте кадров, и сценарии анимации не будут выполняться быстрее, если они управляются событием enterFrame (а не таймер).

4 голосов
/ 24 сентября 2008

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

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

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

2 голосов
/ 24 сентября 2008

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

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

0 голосов
/ 25 сентября 2008

Я бы предложил использовать такой класс, как TweenLite (http://blog.greensock.com/tweenliteas3/), который весит около 3 КБ, или, если вам нужно больше энергии, вы можете использовать TweenMax, который, я считаю, составляет 11 КБ. Здесь много преимуществ. Во-первых, этот «движок» был тщательно протестирован и протестирован и хорошо известен как один из наиболее дружественных к ресурсам способов анимации нескольких или даже многих вещей. Я видел эталон, в котором в AS3 1500 спрайтов анимируются с помощью TweenLite, и он имеет сильные 20 кадров в секунду, тогда как конкуренты, такие как Tweener, замедляют работу до 9 кадров в секунду http://blog.greensock.com/tweening-speed-test/. Следующим преимуществом является простота использования как я покажу ниже.

//Make sure you have a class path pointed at a folder that contains the following.
import gs.TweenLite;
import gs.easing.*;

var ball_mc:MovieClip = new MovieClip();
var g:Graphics = ball_mc.graphics;
g.beginFill(0xFF0000,1);
g.drawCircle(0,0,10);
g.endFill();

//Now we animate ball_mc
//Example: TweenLite.to(displayObjectName, totalTweeningTime, {someProperty:someValue,anotherProperty:anotherValue,onComplete:aFunctionCalledWhenComplete});
TweenLite.to(ball_mc, 1,{x:400,alpha:0.5});

Таким образом, это берет ball_mc и перемещает его на 400 из его текущего положения на оси x, и во время того же Tween он уменьшает или увеличивает альфа с текущего значения до 0,5.

После импорта необходимого класса, это всего лишь 1 строка кода для анимации каждого объекта, что очень хорошо. Мы можем также повлиять на легкость, которая, по моему мнению, по умолчанию - Expo.easeOut (Strong easeOut). Если вы хотите, чтобы он отскакивал или был эластичным, такие эффекты можно получить, просто добавив свойство к объекту следующим образом.

TweenLite.to(ball_mc, 1,{x:400,alpha:0.5,ease:Bounce.easeOut});
TweenLite.to(ball_mc, 1,{x:400,alpha:0.5,ease:Elastic.easeOut});

Ослабление всего происходит из gs.easing. * Import, который, я считаю, является уравнением ослабления Пеннера, используемым через TweenLite.

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

Также важно отметить, что TweenLite и TweenMax предлагают гораздо больше, чем я здесь показал, и можно с уверенностью сказать, что я использую один из двух классов в каждом отдельном проекте. Анимации являются пользовательскими, к ним прикреплены функциональные возможности (onComplete: functionCall), и, опять же, они оптимальны и дружественны к ресурсам.

0 голосов
/ 24 сентября 2008

Я думаю, что timerEvent и Enter Frame - это хорошие варианты, я использовал их в своих играх. (Вы имели в виду timerEvent под циклом таймера?)

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

...