Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.1k views
in Technique[技术] by (71.8m points)

apache flex - AS3: How accurate are the getTimer() method and the Timer class?

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...