【问题标题】:Actionscript: Very slow movieclip动作脚本:非常慢的电影剪辑
【发布时间】:2018-02-07 05:00:49
【问题描述】:

我正在不同程度地画一条圆形线。我希望动画持续大约 0.5 秒。由于某些原因,我无法计算出它的运行速度非常慢。

奇怪的是,如果我跳过补间并调用函数 tweenToNext,它会立即呈现。

        var degrees:int;
        var posX:int = 102;
        var posY:int = 102;
        var rad:int = 100;
        var mc:MovieClip = new MovieClip();
        addChild(mc);

        mc.graphics.lineStyle(5, 0xFF0000, 1);
        mc.graphics.moveTo(posX, posY - rad)
        mc.i = -Math.PI / 2;

        tweenToNext();

        function tweenToNext(per:Number = 360):void {

            degrees += 1;

            if (mc.i <= (3 * Math.PI / 2) && degrees < per) {

                var x:Number = posX + Math.cos(mc.i) * rad;
                var y:Number = posY + Math.sin(mc.i) * rad;

                mc.graphics.lineTo(x, y); 
                mc.i += Math.PI / 180;

                TweenLite.to(mc, 0.001, {onComplete:tweenToNext});
            }

        }       

我尝试过 Timer 和 setTimeout,但它们的速度相同。

【问题讨论】:

  • 矢量路径越复杂,渲染越慢。我建议要么查看drawPath(),这应该更有效,或者使用 BitmapData 实例来绘制线条。
  • 看看this answer
  • 另外请不要嵌套函数,你可能会误以为它们依赖于外部声明的变量。
  • Organis 是在正确的轨道上,但我有一个建议。而不是补间 0.0001 毫秒(现在来吧;)),根据您的帧速率进行补间。如果您的 FPS 为 30,则一帧需要 33.3 毫秒。

标签: actionscript-3 actionscript


【解决方案1】:

Flash 应用程序逐帧运行:帧渲染 - 脚本执行 - 帧渲染 - 脚本执行 - 帧渲染 - 脚本执行 - 等等。这也意味着无论您放在那里的最小延迟,下一个调用不会发生在下一个脚本执行阶段之前,基本上是下一帧。因此 - 你猜怎么着 - 你的圆圈画需要 360 帧。例如,如果您有 30 FPS,则为 12 秒。

如果你想让某些东西与实时同步,你需要一种不同的方法。我没有检查这是否有效,但我希望你能理解并纠正错误。

var degrees:int;

var posX:int = 102;
var posY:int = 102;

var rad:int = 100;

var mc:MovieClip = new MovieClip;

addChild(mc);

mc.graphics.lineStyle(5, 0xFF0000, 1);
mc.graphics.moveTo(posX, posY + rad);

// Now, magic time.
// Save time since app start (in milliseconds).
var startTime:int = getTimer();

// 1000 milliseconds = 1 second.
var drawingTime:int = 1000;

// Store the maximum degree to draw.
var degreeLimit:int = 360;

// Call it every frame.
mc.addEventListener(Event.ENTER_FRAME, onDraw);

function onDraw(e:Event):void
{
    // Now we need to check how much time passes since last frame
    // and update the drawing accordingly.
    var timeProgress:Number = (getTimer() - startTime) / drawingTime;
    var drawingProgress:Number = degrees / degreeLimit;

    // When the drawing progress catches the time progress
    // the loop will end. It will resume on the next frame.
    while (drawingProgress < timeProgress)
    {
        degrees += 1;

        // It's better than a property on target canvas,
        // which could be Sprite or Shape, they wouldn't take random fields.
        var anAngle:Number = degrees * Math.PI / 180;

        var tox:Number = posX + Math.cos(anAngle) * rad;
        var toy:Number = posY + Math.sin(anAngle) * rad;

        mc.graphics.lineTo(tox, toy);

        // We should know when to stop it.
        if (dergees >= degreeLimit)
        {
            mc.removeEventListener(Event.ENTER_FRAME);
            return;
        }

        // Update the drawing progress.
        drawingProgress:Number = degrees / degreeLimit;
    }
}

【讨论】:

    猜你喜欢
    • 2015-04-24
    • 2011-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-05
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    相关资源
    最近更新 更多