Actionscript 3.0: В чем разница между использованием события ENTER_FRAME и события TIMER для метода обновления? - PullRequest
2 голосов
/ 10 марта 2012

Я ищу некоторое сравнение между методами ENTER_FRAME и TIMER при использовании их для метода обновления.Я искал ответы в Интернете, но мне все еще трудно это понять.

Может ли кто-нибудь помочь с упрощением различий между ними?

Ответы [ 4 ]

5 голосов
/ 11 марта 2012

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

Кроме того, таймеры могут быть полезны, если вы хотите, чтобы определенное действие происходило после заданной задержки. Например, Таймер позволяет легко выполнить действие через 10 секунд. Вы просто передаете 10000 миллисекунд в конструктор вашего Timer, а затем событие Timer будет отправлено через 10 секунд. Если бы вы использовали ENTER_FRAME, вам нужно было бы вручную отслеживать время, прошедшее при каждом обновлении кадра, если вы хотите знать, когда прошло 10 секунд.

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

2 голосов
/ 11 марта 2012

"enterFrame" отправляется на каждый кадр.

Предположим, ваш SWF составляет 24 кадра в секунду: "enterFrame" будет отправляться до 24 раз каждую секунду.

"timer" отправляется с заданным интервалом.

Предположим, что вы запускаете Timer с задержкой в ​​50 миллисекунд: "timer" будет отправляться до 20 раз каждую секунду.

Фактическая частота этих событий будет зависеть от среды хоста, а также от того, что происходит внутри вашего приложения. Например, если внутри обработчика "timer" есть цикл for, в котором вы выполняете итерацию по массиву из 1000 элементов и выполняете некоторые манипуляции со строками для каждого элемента, то вы, скорее всего, получите меньше событий "timer", чем если бы Ваш массив содержал только 10 элементов. Аналогично, если в системе пользователя недостаточно свободной памяти, у Flash Player могут возникнуть проблемы с выполнением SWF-файла, что может снизить скорость отправки этих событий.

"enterFrame" напрямую зависит от частоты кадров. "timer" зависит несколько косвенно от частоты кадров.

Поскольку вы (или кто-то еще) непременно спросите, что я имею в виду под «несколько косвенным образом», вот небольшое приложение AS3, которое проверяет оба события:

package
{

import flash.display.*;
import flash.events.*;
import flash.utils.*;

public class Test extends Sprite
{
    private var timer:Timer = null;
    private var timerEventCount:int = 0;
    private var enterFrameEventCount:int = 0;
    private var startTime:Number = 0;

    public function Test()
    {
        timer = new Timer(20, 0);
        timer.addEventListener("timer", timerHandler);
        timer.start();

        addEventListener("enterFrame", enterFrameHandler);

        startTime = new Date().time;
    }

    private function timerHandler(event:Event):void
    {
        timerEventCount++;

        var timeElapsed:Number = new Date().time - startTime;

        //for (var i:int = 0; i < 4000; i++)
        //  trace("i", i);

        if (timeElapsed >= 1000) {
            // Stop timer after 1 second.
            timer.stop();

            removeEventListener("enterFrame", enterFrameHandler);

            trace(timerEventCount + " timer events and "
                    + enterFrameEventCount + " enterFrame events in "
                    + timeElapsed + " milliseconds.");
        }
    }

    private function enterFrameHandler(event:Event):void
    {
        enterFrameEventCount++;
    }
}

}

Компиляция со скоростью 12 кадров в секунду:

mxmlc Test.as -default-frame-rate=12

Выход:

45 timer events and 12 enterFrame events in 1001 milliseconds.

Компиляция со скоростью 60 кадров в секунду:

mxmlc Test.as -default-frame-rate=60

Выход:

29 timer events and 58 enterFrame events in 1010 milliseconds.

Как видите, более высокая частота кадров на самом деле замедляет таймер. Я запускаю это в Flash Player Debugger 10.3.181.34 (10.3); Ваш пробег может варьироваться.

Наконец, если вы раскомментируете цикл for и запустите его снова с 60fps, вы поймете, о чем я говорю.

Выход:

3 timer events and 3 enterFrame events in 1145 milliseconds.
1 голос
/ 11 марта 2012

ENTER_FRAME - это событие, которое запускается каждый раз при запуске цикла рендеринга виртуальной машины, и это зависит от частоты кадров фильма.Например, в IDE Flash CS, если вы установите частоту кадров 30, то из корневого экранного объекта или сцены будет происходить 30 событий ENTER_FRAME каждую секунду.

С другой стороны, таймер - это простотаймерОн работает исключительно на основе системного времени.Например, если вы установите таймер с задержкой в ​​1 миллисекунду, то этот таймер сработает через одну миллисекунду после запуска и продолжит срабатывать один раз в каждую миллисекунду, если вы его включите.Я думаю, что Камю пытался сказать в своем ответе, что этот процесс работает независимо от частоты кадров.Он основан исключительно на проверке системных часов и инициировании событий для таймеров, которые выполнили запрошенную задержку.Это проверяется внутренне, сохраняя системное время, в которое был запущен таймер, а затем повторно проверяя текущее системное время, пока оно не станет больше или равно сохраненному времени, плюс задержка таймеров.Пример:

timer.start() //Lets say current system time is 1000

Продолжительность таймера равна 1000, поэтому мы должны запустить этот таймер, когда системное время больше или равно 2000.

checkTimers() //Loops, gets the current system

//If system time is greater than or equal to 2000, trigger timer with an event
dispatchEvent(Timer.TIME, etc, etc);

Обратите внимание, что приведенный выше код"это просто псевдокод, демонстрирующий основные принципы системы.

0 голосов
/ 10 марта 2012

ENTER_FRAME - это частота кадров фильма. Таймер событий должен быть абсолютным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...