代码之家  ›  专栏  ›  技术社区  ›  jorelli

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

  •  3
  • jorelli  · 技术社区  · 17 年前

    我正在制作一个游戏(shmup),我开始质疑ActionScript中计时器的准确性。当然,当你想在几秒或几分秒的量级上计时时,它们足够准确,但当你达到更精细的范围时,它的表现似乎相当糟糕。这使得像让宇宙飞船每秒发射一百个激光这样的事情变得相当困难。

    • 这些结果会在其他机器上发生巨大变化吗?

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

    编辑:我使用stage.frameRate更改了渲染帧率,并在几个帧率上运行了测试,但没有变化。

    5 回复  |  直到 17 年前
        1
  •  4
  •   Luke    17 年前

    Tinic Uro(Flash Player工程师)写了一篇 interesting blog

        2
  •  2
  •   Jacob Poul Richardt    17 年前

    为了使用计时器类,我会把我的更新代码放进去并输入事件监听器。

    然后使用getTimer(),找出自上次更新以来已经过去了多长时间,然后进行一些数学运算来计算移动、激光“产卵”等。这样,无论你获得60FPS还是10FPS,游戏的表现都应该是一样的。

    我从来没有遇到过键盘问题。也许你应该试试这个漂亮的小班: http://www.bigroom.co.uk/blog/polling-the-keyboard-in-actionscript-3

        3
  •  1
  •   fenomas    17 年前

    运行逻辑帧外事件的另一种自然方式是制作一个“理论上”每T毫秒运行一次的游戏循环。然后,在你的 ENTER_FRAME 处理程序,只需迭代该循环F/T次,其中F是自上一帧事件以来经过的毫秒数。因此,如果你希望游戏理论上每5ms更新一次,并且你希望屏幕以30FPS更新,你只需以30FPS发布,然后在你的 处理器,你会连续调用主游戏循环5-7次,具体取决于自上一帧以来的时间。在屏幕上,这将为您提供与使用5ms定时器事件相同的结果,并且可以免除大部分开销。

        4
  •  1
  •   Tim Kerchmar    15 年前

    BitmapData.scroll和BitmapData.copyPixels是目前在flash中渲染最快的方法,尽管在一些系统上,使用gpu加速的电影剪辑稍微快一些。每个四边形在OpenGL中都被渲染为一个单独的纹理,所以这不是你对普通GPU加速应用程序的期望。我知道,因为我在比赛中分析了这两种方式。为了提高响应时间,您可以从输入事件处理程序调用游戏更新。这样,即使游戏的帧速率较低,您也能听到正确计时的声音,应用程序也会感觉更灵敏。

        5
  •  0
  •   Ryan Guill    17 年前

    这给了我大约60的最大帧率,这在视觉上很棒,但也意味着我不可能每秒发射超过60个激光:-(

    推荐文章