AS3:getTimer() 方法和 Timer 类的准确度如何? [英] AS3: How accurate are the getTimer() method and the Timer class?

查看:31
本文介绍了AS3:getTimer() 方法和 Timer 类的准确度如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作游戏(shmup)并且我开始质疑 ActionScript 中计时器的准确性.当然,当您想以几秒或几分秒为单位计时时,它们已经足够准确,但是当您达到更精细的范围时,它的性能似乎很差.这使得像让宇宙飞船每秒发射 100 束激光这样的事情变得非常困难.

在以下示例中,我测试了 30 毫秒内 1000 个计时器滴答之间的时间间隔(平均).一次又一次,结果是~35-36ms.减少时间,我发现定时器延迟的底限为~16-17ms.这给了我 ~60 的最大 fps,这在视觉上很棒,但也意味着我不可能每秒发射超过 60 个激光:-(.我在 100 和 1000 次循环中运行了几次这个测试,但对于这两个30ms 测试和 1ms 测试结果没有改变.我最后打印到 textField,因为使用 trace() 并在调试模式下启动 swf 似乎对测试产生负面影响.所以我想知道的是:

  • 此测试是否可以很好地衡量 Timer 课程的表现,还是我的结果有问题?
  • 这些结果在其他机器上会发生显着变化吗?

我知道这取决于 getTimer() 方法的准确性,但我发现关于此主题的讨论通常围绕 getTimer() 在较大间隔上的准确性.

打包{
导入 flash.display.Sprite;导入 flash.events.TimerEvent;导入 flash.text.TextField;导入 flash.utils.getTimer;import flash.utils.Timer;

公共类 testTimerClass 扩展了 Sprite{private var testTimer:Timer = new Timer(30, 1000);私有 var testTimes:Array = new Array();私有变量 testSum:int = 0;私有变量 testAvg:Number;私有变量 lastTime:int;私有变量 thisTime:int;公共函数 testTimerClass(){testTimer.addEventListener(TimerEvent.TIMER, step);testTimer.addEventListener(TimerEvent.TIMER_COMPLETE, printResults);lastTime = getTimer();testTimer.start();}私有函数 step(event:TimerEvent):void{thisTime = getTimer();testTimes.push(thisTime - lastTime);上次 = 这次;}私有函数 printResults(event:TimerEvent):void{while (testTimes.length > 0){testSum += testTimes.pop();}testAvg = testSum/Number(testTimer.repeatCount);var txtTestResults:TextField = new TextField();txtTestResults.text = testAvg.toString();this.addChild(txtTestResults);}}

}

我想最好的方法是在同一帧中以不同的位置绘制多个激光,并避免使用多个 Timer 对象.

我使用 stage.frameRate 来更改渲染帧率并在几个帧率上运行测试,但没有任何变化.

解决方案

Tinic Uro(Flash Player 工程师)编写了一个 有趣的博客 前段时间关于这个问题的帖子.

I'm in the process of making a game (a shmup) and I've started to question the accuracy of the timers in ActionScript. Sure, they're accurate enough when you want to time things on the order of a few seconds or deciseconds, but it seems to perform pretty poorly when you get to finer ranges. This makes it pretty tough to do things like have a spaceship firing a hundred lasers per second.

In the following sample, I tested how long (on average) the intervals were between 1000 timer ticks intended for 30ms. Time and time again, the results are ~35-36ms. Decreasing the time, I found the floor on the timer delay to be ~16-17ms. This gives me a max fps of ~60, which is great visually but also means I can't possibly fire more than 60 lasers per second :-(. I ran this test a few times at 100 and 1000 loops, but for both the 30ms test and the 1ms test the results didn't change. I print to a textField at the end because using trace() and launching the swf in debug mode seems to negatively affect the test. So what I'm wondering is:

  • Is this test a decent measure of the Timer class's performance, or are my results questionable?
  • Will these results change dramatically on other machines?

I understand this is dependent on the getTimer() method's accuracy, but the discussions I find on this topic usually center around getTimer()'s accuracy on larger intervals.

package 
{
import flash.display.Sprite; import flash.events.TimerEvent; import flash.text.TextField; import flash.utils.getTimer; import flash.utils.Timer;

public class testTimerClass extends Sprite
{
    private var testTimer:Timer = new Timer(30, 1000);
    private var testTimes:Array = new Array();
    private var testSum:int = 0;
    private var testAvg:Number;
    private var lastTime:int;
    private var thisTime:int;

    public function testTimerClass()
    {
        testTimer.addEventListener(TimerEvent.TIMER, step);
        testTimer.addEventListener(TimerEvent.TIMER_COMPLETE, printResults);
        lastTime = getTimer();
        testTimer.start();
    }

    private function step(event:TimerEvent):void
    {
        thisTime = getTimer();
        testTimes.push(thisTime - lastTime);
        lastTime = thisTime;
    }

    private function printResults(event:TimerEvent):void
    {
        while (testTimes.length > 0)
        {
            testSum += testTimes.pop();
        }
        testAvg = testSum / Number(testTimer.repeatCount);              
        var txtTestResults:TextField = new TextField();
        txtTestResults.text = testAvg.toString();
        this.addChild(txtTestResults);  
    }       
}

}

I guess the best route to take would be to just draw multiple lasers in the same frame with different positions and avoid having more than one Timer object.

edit: I used stage.frameRate to change the render frameRate and ran the test on several framerates but there was no change.

解决方案

Tinic Uro (Flash Player engineer) has written an interesting blog post about this issue some time ago.

这篇关于AS3:getTimer() 方法和 Timer 类的准确度如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆