【问题标题】:AS3: Large number of timers lagging flashAS3:大量定时器滞后闪烁
【发布时间】:2012-09-24 07:05:59
【问题描述】:

我有大量对象 (472) 需要一个计时器,用于检查变量的状态更改之间需要多长时间。下面的代码是我目前所拥有的,但运行的许多计时器肯定会影响应用程序的性能,是否有更好的优化方法来衡量这一点?

import flash.utils.Timer;

var active_:Boolean;
var matched:Boolean;
var vacated:Boolean;

var circ:Shape=new Shape();
this.addChild(circ);
circ.x = 0;
circ.y = 0;
var circRad:Number = 5;
var mat= new Matrix();
var busyColors = [0xFFFF00,0xFFCC00];
var idleColors = [0xCCCCCC,0x000000];
var matchedColors = [0x0099FF,0x0066FF];
var vacatedColors = [0xFF0000,0x990000];
var busyAlphas = [1,1];
var idleAlphas = [0.5,0.5];
var ratios = [0,255];
var prev:int = 0;
var time:Timer = new Timer(1000,0);
//time.start();
mat.createGradientBox(2*circRad,2*circRad,0,-circRad,-circRad);
circ.graphics.lineStyle();
if (active_ == false)
{
    if (prev != 0)
    {
        setAverage(prev,false);
        prev = 0;
    }
    circ.graphics.clear();
    circ.graphics.beginGradientFill(GradientType.RADIAL,idleColors,idleAlphas,ratios,mat);
    circ.graphics.drawCircle(0,0,circRad);
    circ.graphics.endFill();
}
else if (active_ == true && matched == true)
{
    if (prev != 1)
    {
        setAverage(prev,true);
        prev = 1;
    }
    circ.graphics.clear();
    circ.graphics.beginGradientFill(GradientType.RADIAL,matchedColors,busyAlphas,ratios,mat);
    circ.graphics.drawCircle(0,0,circRad);
    circ.graphics.endFill();
}
else if (active_ == true && vacated == false && matched == false)
{
    if (prev != 2)
    {
        setAverage(prev,true);
        prev = 2;
    }
    circ.graphics.clear();
    circ.graphics.beginGradientFill(GradientType.RADIAL,busyColors,busyAlphas,ratios,mat);
    circ.graphics.drawCircle(0,0,circRad);
    circ.graphics.endFill();
}
else if (active_ == true && vacated == true)
{
    if (prev != 3)
    {
        setAverage(prev,true);
        prev = 3;
    }
    circ.graphics.clear();
    circ.graphics.beginGradientFill(GradientType.RADIAL,vacatedColors,busyAlphas,ratios,mat);
    circ.graphics.drawCircle(0,0,circRad);
    circ.graphics.endFill();
}

function setAverage(i:int, a:Boolean)
{
    time.stop();
    switch (i)
    {
        case 0 :
            break;

        case 1 :
            MovieClip(root).avgMat.push(uint(time.currentCount));
            break;

        case 2 :
            MovieClip(root).avgBusy.push(uint(time.currentCount));
            break;

        case 3 :
            MovieClip(root).avgVac.push(uint(time.currentCount));
            break;
    }
    if(a == true){
        //time.reset();
        //time.start();
    }   
}

注释掉由于问题而启动的计时器。

【问题讨论】:

    标签: actionscript-3 flash optimization actionscript timer


    【解决方案1】:

    您可以在您的对象上创建像“tick()”这样的公共函数,并从外部的 1 个通用计时器循环调用它。

    【讨论】:

    • 如果对象不是同时创建的,用'tick'算秒不是不准确吗?他可能需要为每个实例设置不同的时间指示器。
    • 没错,每一件事都是一个单独的实例,我能想到的唯一方法是在根上创建一个计时器并每次都取不同。
    • 您可以设置间隔为 1/30 秒的计时器,并在滴答之前检查“帧到期”。它会更频繁,但不像计时器那样广泛。
    • 我已经设法用一个计时器设置了我上面提到的内容,但我似乎无法将值推回根上的数组。如果我指定MovieClip(root),那将到达最高点是吗?
    • 我想说在您的任何对象中使用单个输入帧侦听器,这样您就可以随时访问舞台。并使用该侦听器调用tick(),就像在您可用的任何东西上建议的那样 - 您将需要这些或类似的数组,并在整个过程中维护它。
    【解决方案2】:

    考虑执行以下操作:

    在顶部,导入ge​​tTimer

    import flash.utils.Timer;
    

    创建一个包含开始时间的变量(而不是执行 timer.start),这样做:

    var timerStart : int = getTimer();
    

    而不是这样做:time.currentCount

    只需这样做:

    (getTimer() - timerStart) / 1000
    

    祝你好运。

    【讨论】:

    • 解决了我的问题。 Timer.currentCound 在移动设备中是不正确的,尤其是在使用 Adob​​e AIR 时。
    【解决方案3】:

    您可以使用 EVENT FRAME 类型的 addEventListener 更改所有计时器

    var counter:Number = 0;
    addEventListener(Event.ENTER_FRAME, counting);
    function counting (e:Event):void
    {
         counter++
    }
    

    所以计数器会在每一帧上递增。现在你必须找到fps。现在将 fps 乘以您希望计时器运行的时间。所以它应该是这样的:

    var counter:Number = 0;
    addEventListener(Event.ENTER_FRAME, counting);
    function counting (e:Event):void
    {
         counter++
         if(counter == 60) //60 fps means this line will run after 1 sec.
         {
              //do something
         }
         If(counter == 120) //60 fps; 2 sec
         {
              //do something
         }
    }
    

    这种方法更准确,系统不会那么过载。当您在动画开始后需要延迟时,这可以特别帮助您使用 addChild 设置舞台。

    你可以制作更多的“计时器”,但这取决于游戏的需求,但我相信它会比数百个计时器更快。

    【讨论】:

    • 看到该方法的问题是,如果应用程序滞后,那么时间也会滞后。我也认为我需要发生的事情很混乱。基本上我有大约 470 个“节点”,每个节点都有 4 个状态之一。我需要在一个数组中记录这些节点处于其中 3 个状态的时间量。然后在数组上运行平均函数以返回单个平均值。
    猜你喜欢
    • 1970-01-01
    • 2011-02-24
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多