AS3计时器或帧速率

时间:2013-02-26 05:06:21

标签: actionscript-3 timer

好的,所以我听说基于计时器的运动比FR一样好。 V = V + n / 1/60秒,而不是每帧@ 60 fps。他们说它使速度变得实际,而不是因为FR滞后而减少。但是当我尝试它时,计时器真的不可靠。难道我做错了什么?导致定时器(20,0)随着动画的进展而变慢。所以没有什么区别,如果剪辑超重,它会慢下来无论基于计时器还是FR?是的,我有一个测试片段,每秒都有新的形状,所以一段时间后会有相当多的但计时器真的比我的时钟慢,秒变长。但计时器是额外的工作要做,更令人头痛。 所以这不值得,或者我错了吗?(在其他功能之前没有优先考虑?)

4 个答案:

答案 0 :(得分:4)

是的,如果您的SWF能够在不到一帧的长度内渲染舞台,两者都很好,如果不是,无论您做什么,您的帧率都会受到影响。如果你想要这个大FPS,你需要调整你的SWF以获得性能。此外,计时器无法比每帧一次更快地触发其事件。 (事实上​​我认为帧时间方法通常更好,因为你不知道你的SWF是否会在足够慢的PC上运行,否则它将无法与正常的时间流竞争。)

在你的情况下,我会丢弃定时器,他们每帧再抛出一个事件,它们在很大程度上是不可靠的,因为它们的事件是异步的,这意味着你不能一直说定时器事件将在下一帧之前触发,并且间隔更大定时器,主机PC稍有滞后可能会破坏许多玩家的乐趣。 (我记得Pyro和我的旧PIII,它使用系统时间来记录水平节拍时间,但是一旦你发射那个球你就无法加速它,并且动画足够重以降低帧速率,从根本上阻止我快速时间分数。)你的计时器已经每帧发射一次事件,并且无法加快速度。

答案 1 :(得分:2)

AS3中的计时器确实不可靠。 AS3中的计时器的值不能低于1000.这是Adobe正式记录的。你也可以测试一个1000ms限制的计时器,你会发现它会以800-999ms的间隔随机发射,这是绝对准确的。

如果你想制作一个框架限制/免费应用程序,一个更好的候选人是“getTimer”。您可以使用传递的ms量来计算传递的正确时间量,然后渲染帧。

查看此项目中的Clock类: Realtime Clock

答案 2 :(得分:1)

你没有做错任何事。它不太理想,但Flash限制更新到最大帧速率,这意味着Timer事件不准确。就个人而言,我倾向于使用基于帧的循环来使时间敏感,使用new Date().getTime()来检查当前系统时间,所以我会使用类似的东西:

private var lastFrameTime:Number = new Date().getTime();
private var now:Number;

addEventListener(Event.ENTER_FRAME, frameTick);

private function frameTick(e:Event):void {
    now = new Date().getTime();
    V = V + n * (now - lastFrameTime) * 0.001;
    lastFrameTime = now;
}

答案 3 :(得分:0)

可能会有所帮助。

public class Timer extends EventDispatcher
{
    private var instance:int;
    private var _interval:Number;
    private var _updateInterval:uint;
    private var _lastCount:int
    private var _repeatCount:int;
    private var _count:int;
    private var _started:Boolean;
    public function Timer(interval:Number,repeatCount:int=0)
    {
        _interval=interval;
        _repeatCount=repeatCount;
    }

    private function checkTime():void
    {
        var curCount:int=int(currentTime()/_interval);
        if(curCount<=_lastCount)return;

        _lastCount=curCount
        _count++;

        dispatchEvent(new TimerEvent(TimerEvent.TIMER));

        if(_count==_repeatCount&&_repeatCount>0)
        {
            stop();
            dispatchEvent(new TimerEvent(TimerEvent.TIMER_COMPLETE));
            _count=0;
        }
    }
    public function start():void
    {
        if(_started)return;
        _started=true;
        instance = getTimer();
        _updateInterval=setInterval(checkTime,10);

        _lastCount=int(currentTime()/_interval);
    }
    public function stop():void
    {
        _started=false;
        clearInterval(_updateInterval);
    }
    public function reset():void
    {
        _count=0;
        stop();
        start();
    }
    private function currentTime():Number
    {
        if (instance == 0)
        {
            instance = getTimer();
        }
        return (getTimer() - instance);
    }
    public function get currentCount():int
    {
        return _count;
    }
}