4

好的,所以我听说基于计时器的运动比 FR 更好。V = V + n 每 1/60 秒,而不是每帧 @ 60 fps。他们说它使速度变得实际,而不是因为 FR 滞后而降低。但是当我尝试过时,计时器真的一点也不可靠。难道我做错了什么?原因 Timer(20,0) 随着动画的进行而变慢。所以没有区别,如果剪辑超重,无论基于计时器还是FR,它都会减慢速度?是的,我有一个测试剪辑,每秒钟都会做出新的形状,所以一段时间后会有很多,但计时器真的比我的时钟慢,秒变长。但是计时器是额外的工作要做,更令人头疼。所以这不值得还是我用错了?(没有让它优先于其他功能吗?)

4

4 回答 4

4

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

在您的情况下,我会放弃计时器,它们每帧再抛出一个事件,它们在很大程度上是不可靠的,因为它们的事件是异步的,这意味着您不能始终说计时器事件将在下一帧之前触发,并且使用更大的间隔计时器,a主机 PC 的任何延迟都会破坏许多玩家的乐趣。(我记得 Pyro 与我的旧 PIII,它使用系统时间来记录关卡节拍时间,但是一旦你开球就无法加快速度,而且动画重到会降低帧率,基本上阻止了我快速时间分数。)您的计时器已经在每帧大约触发一次事件,并且无法变得更快。

于 2013-02-26T05:32:13.563 回答
2

AS3 中的定时器确实不可靠。AS3 中的计时器的值不能低于 1000。Adobe 正式记录了这一点。您还可以对限制为 1000 毫秒的计时器进行测试,您会注意到它会以 800-999 毫秒的间隔随机触发,这永远不会准确。

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

看一下这个项目中的Clock类: Realtime Clock

于 2013-02-26T05:39:49.713 回答
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;
}
于 2013-02-26T06:00:34.427 回答
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;
    }
}
于 2013-10-30T12:03:07.560 回答