В нашем игровом проекте у нас был таймер, настроенный на срабатывание примерно 20 раз в секунду (то же самое, что и частота кадров приложения). Мы используем это, чтобы перемещать некоторые спрайты. Мне интересно, может ли это вызвать проблемы, и мы должны вместо этого выполнять наши обновления с помощью обработчика событий EnterFrame? У меня сложилось впечатление, что если цикл таймера работает быстрее, чем частота кадров приложения, это может вызвать проблемы ... так ли это?
В качестве обновления попытка сделать это в EnterFrame вызвала очень странные проблемы. Вместо кадра каждые 75 мс он внезапно подскочил до 25 мс. Обратите внимание, это был не просто наш расчет утверждал, частота кадров была другой, внезапно анимация ускорилась до сумасшедшей скорости.
Большая часть игры - это чистый AS3, загружающий множество файлов SWF, созданных CS3. Однако мы используем MXML для пользовательского интерфейса, что, я думаю, дает лучшее из обоих миров. Я должен добавить, что проблемы с производительностью возникают только тогда, когда мы пытаемся загрузить особенно большие игровые уровни ... обычно это нормально.





Я думаю, что timerEvent и Enter Frame - хорошие варианты, я использовал их оба в своих играх. (Вы имели в виду timerEvent под циклом таймера?)
PS: обратите внимание, что на медленных машинах таймер может обновляться недостаточно быстро, поэтому вам может потребоваться настроить код, чтобы игра работала «быстрее» на медленных машинах.
Я бы выбрал фрейм Enter, в некоторых особых случаях может быть полезно иметь два «цикла»: один для логики и один для визуальных эффектов, но для большинства игр я использую прослушиватель событий кадра Enter. Наличие отдельного таймера для перемещения ваших вещей немного излишне, поскольку установка для него чего-либо, кроме частоты кадров, сделает движение рывчатым или просто невидимым (поскольку кадр не перерисовывается).
Одна вещь, которую следует учитывать, - это отделить вашу логику от частоты кадров, это проще всего сделать, используя getTimer (доступный как в as2, так и в as3) для расчета времени, истекшего с момента последнего кадра, и корректировки движений или чего-то еще.
Таймер не более надежен, чем событие входа в кадр, вспышка будет пытаться не отставать от установленной вами скорости, но если вы выполняете тяжелую обработку или сложную графику, она будет замедляться, как таймеры, так и частота кадров.
Приятная вещь в использовании событий ввода кадра заключается в том, что ваша обработка будет ухудшаться с той же скоростью, что и рендеринг, и вы получите обновление экрана сразу после завершения блока кода.
Ни один из этих методов не гарантированно сработает в определенный промежуток времени. Таким образом, ваш обработчик событий должен определять, сколько времени прошло с момента его последнего выполнения, и принимать решения на основе этого, а не просто сколько раз он запускался.
Я бы предложил использовать такой класс, как TweenLite (http://blog.greensock.com/tweenliteas3/), который имеет небольшой вес около 3 КБ, или, если вам нужно больше мощности, вы можете использовать TweenMax, который, как я считаю, составляет 11 КБ. Здесь много преимуществ. Во-первых, этот «движок» был тщательно протестирован и протестирован и хорошо известен как один из наиболее ресурсосберегающих способов оживить некоторые или даже многие вещи. Я видел тест, в котором в AS3 1500 спрайтов анимируются с помощью TweenLite, и он показывает сильные 20 кадров в секунду, тогда как у конкурентов, таких как Tweener, http://blog.greensock.com/tweening-speed-test/ упадет до 9 кадров в секунду. Следующее преимущество - простота использования, как я продемонстрирую ниже.
//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.
После импорта необходимого класса для анимации каждого объекта остается только одна строка кода, что действительно приятно. Мы также можем повлиять на легкость, которую я считаю по умолчанию Expo.easeOut (Strong easyOut). Если вы хотите, чтобы он отскакивал или был эластичным, такие эффекты можно получить, просто добавив свойство к объекту, как показано ниже.
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. *, Который, как я считаю, является уравнениями ослабления Пеннера, используемыми через TweenLite.
В конце концов, у нас нет опросов (открытых циклов) для управления, таких как Timer, и у нас есть очень читаемый код, который можно легко изменить или удалить.
Также важно отметить, что TweenLite и TweenMax предлагают гораздо больше, чем я показал здесь, и можно с уверенностью сказать, что я использую один из двух классов в каждом отдельном проекте. Анимации являются настраиваемыми, к ним прикреплены функциональные возможности (onComplete: functionCall), и, опять же, они оптимальны и удобны для ресурсов.
Вот краткое изложение того, как Flash обрабатывает частоту кадров и почему вы видели, что ваш контент воспроизводится быстрее.
На самом глубоком уровне любое хост-приложение, в котором работает Flash (обычно браузер), опрашивает вспышку через некоторый интервал. Этот интервал может составлять каждые 10 мс в одном браузере или 50 мс в другом. Каждый раз, когда происходит опрос, Flash делает что-то вроде этого:
ENTER_FRAMEОднако определенные виды внешних событий (например, нажатия клавиш, события мыши и события таймера) обрабатываются асинхронно с вышеуказанным процессом. Поэтому, если у вас есть обработчик событий, который запускается при нажатии клавиши, код в этом обработчике может выполняться несколько раз между обновлениями кадров. Экран по-прежнему будет перерисовываться только один раз при обновлении кадра, если вы не используете метод updateAfterEvent() (глобальный в AS2, привязанный к событиям в AS3).
Обратите внимание, что асинхронное поведение этих событий не влияет на время обновления кадров. Даже если вы используете события таймера, например, для перерисовки экрана 50 раз в секунду, анимация кадра все равно будет происходить с опубликованной частотой кадров, а сценарии анимации не будут выполняться быстрее, если они управляются событием enterFrame (а не таймер).
вы действительно делаете игру, используя фреймворк или просто кодируете ее в as3, используя флексбилдер?