AS3:有多准确的getTimer()方法和Timer类?有多、准确、方法、getTimer

2023-09-08 11:05:23 作者:剧情再美ヽ终究是戏

我在做一个游戏(一shmup)的过程中,我已经开始质疑在ActionScript定时器的准确性。当然,他们是不够准确,当你想不想来一次的东西几秒钟或deciseconds的量级,但它似乎不佳执行pretty的,当你到更精细的范围。这使得它pretty的很难做的事情一样有一个飞船发射每秒一百激光器。

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.

在下面的示例,我测试的间隔时间有多长(平均)分别在1000计时器滴答用于30毫秒。一次又一次,结果是〜35-36ms。减少的时候,我发现地板上的计时器延迟是〜16-17ms。这给了我〜60最大的FPS,这是伟大的视觉,也意味着我不可能解雇每秒:-( 60多个激光器。我跑这个测试了几次,在100和1000环,但无论是。30ms的测试和1ms的测试结果并没有改变我打印到TextField在最后,因为使用trace()和启动SWF在调试模式似乎在测试产生消极影响那么是什么我不知道的是:

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:

这是测试的定时器类的性能体面的措施,或者是我的成绩有疑问? 在将这些成果显着其他机器上的变化?

据我所知,这是取决于中的getTimer()方法的准确度,但讨论,我觉得对这个话题通常围绕的getTimer()的精度中心在更大的区间。

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);	
	}		
}

}

我想取是只绘制多个激光器在同一帧不同的位置,并避免多个Timer对象的最佳途径。

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.

编辑:我用stage.frameRate改变渲染帧率和运行测试在几个帧速率,但并没有改变

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

推荐答案

Tinic乌罗(Flash播放器工程师)写了一本的有趣的博客张贴关于这个问题前一段时间。

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