flash as3 - 一起使用tweenmax和flash的图形类

时间:2011-11-23 17:38:42

标签: flash actionscript-3 graphics drawing tween

我正试图找到一个很好的方法来同时使用TweenMax和flash的绘图类,但它总是陷入困境并崩溃flash播放器,我无法弄清楚出了什么问题。我真正想做的就是确保当一条线连接的两个(或更多个)圆移动时,它们之间的线跟随。这是我的代码:

import com.greensock.TweenMax;

var sw = stage.stageWidth;
var sh = stage.stageHeight;
var cr = 3; //circle radius
var moveRange = 20;
var circleColor = 0xcccccc;
var numCircles = 2;
var circleArray = [];
var lineCanvas:Sprite = new Sprite();
addChild(lineCanvas);
var lineColor = 0xe9e9e9;
var lineWeight = 1;

function init(){
    drawCircle();
}

function drawCircle(){
    for (var i = 0; i<numCircles; i++){
        var xPos = randomRange(cr, sw-cr);
        var yPos = randomRange(cr, sh-cr);
        var newCircle:Shape = new Shape();
        newCircle.graphics.beginFill(circleColor);
        newCircle.graphics.drawCircle(0,0,cr);
        newCircle.x = xPos;
        newCircle.y = yPos;
        newCircle.graphics.endFill();
        circleArray.push(newCircle);
        addChild(newCircle);
    }
    drawLine();
}

function drawLine(){
    for (var i = 0; i<numCircles-1; i++){
        lineCanvas.graphics.clear();
        lineCanvas.graphics.lineStyle(lineWeight,lineColor);
        lineCanvas.graphics.moveTo(circleArray[i].x,circleArray[i].y);
        lineCanvas.graphics.lineTo(circleArray[i+1].x,circleArray[i+1].y);
    }
    moveCircle();
}

function moveCircle(){
    for (var i = 0; i<numCircles; i++){
        var curX = circleArray[i].x;
        var curY = circleArray[i].y;
        var moveX = randomRange(curX-moveRange,curX+moveRange);
        var moveY = randomRange(curY-moveRange,curY+moveRange);
        //TweenMax.to(circleArray[i],.5, { x: moveX, y: moveY, onUpdate:drawLine });
    }
}

function randomRange(minNum:Number, maxNum:Number):Number {  
    return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);  
}

init();

有更好的方法吗?我不应该使用补间库吗?

2 个答案:

答案 0 :(得分:3)

假设您取消注释TweenMax行,函数drawLine()调用moveCircle() ...为每个圈子添加一个补间,再次调用drawLine() - 一切都重复。我想这会增加吨*的监听器和补间,导致崩溃。您应该添加一个检查,以防止添加其他补间,同时还有一个补间仍在为该圈运行。

此外,lineCanvas.graphics.clear();应该在循环之前移动,否则会清除为其他圆圈绘制的线条(如果有的话)。

补间库很好,如果可以,你应该使用一个。即使是简单的补间任务,它们也非常有用。


编辑:
我喜欢数字。假设帧速率为每秒24帧,那么你真的会得到相当多的补间。指数增长。初始化时1个补间,第一个帧中有2个补间,第二个帧中有4个补间,依此类推。当第一个补间完成时(如果它在崩溃之前这样做),你将有很多2 ^ 24-1个补间运行。 16777215少年。对于每个圈子。

但严肃地说,为了解决这个问题,您可以使用TweenMax.isTweening(circleArray[i])来检查是否已经有补间运行。我认为drawLine不应该致电moveCircle。函数moveCircle现在应该只调用一次,以启动补间 - 或者如果你想让它循环,每次补间完成(onComplete)。

答案 1 :(得分:1)

因为mheavers问我,我把一个使用ENTER_FRAME监听器的小例子放在一起,手动为圆圈设置动画。

我有两节课:

package
{
    import flash.filters.BlurFilter;
    import flash.events.Event;
    import flash.display.Sprite;

    [SWF(backgroundColor="#000000", frameRate="60", width="960", height="600")]
    public class Main extends Sprite
    {
        private var numCircles:int = 2;
        private var circles:Vector.<Circle>;
        private var lineCanvas:Sprite;
        private var lineColor:uint = 0xe9e9e9;
        private var lineWeight:int = 1;
        private var blur:BlurFilter;

        public function Main()
        {
            init();
        }

        private function init():void
        {
            circles = new Vector.<Circle>();
            blur = new BlurFilter();

            lineCanvas = new Sprite();
            addChild(lineCanvas);

            drawCircle();

            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }

        private function drawCircle():void
        {
            for (var i:int = 0; i < numCircles; i++)
            {
                var newCircle:Circle = new Circle();
                circles.push(newCircle);
                addChild(newCircle);
            }
            drawLine();
        }

        private function drawLine():void
        {
            var circle:Circle;
            var nextCircle:Circle;
            for (var i:int = 0; i < circles.length-1; i++)
            {
                circle = circles[i];
                nextCircle = circles[i+1];

                //lineCanvas.graphics.clear();
                lineCanvas.graphics.lineStyle(lineWeight, lineColor);
                lineCanvas.graphics.moveTo(circle.x, circle.y);
                lineCanvas.graphics.lineTo(nextCircle.x, nextCircle.y);
            }
        }

        private function onEnterFrame(event:Event):void
        {
            // update circles
            var circle:Circle;
            for (var i:int = 0, len:int = circles.length; i < len; i++)
            {
                circle = circles[i];
                circle.move();
            }

            drawLine();
        }
    }
}

另一个圈子:

package
{
    import flash.events.Event;
    import flash.display.Shape;

    public class Circle extends Shape
    {
        public var targetx:Number;
        public var targety:Number;

        private var circleColor:uint = 0xcccccc;
        private var cr:int = 3;
        private var moveRange:int = 150;

        public function Circle()
        {
            graphics.beginFill(circleColor);
            graphics.drawCircle(0, 0, cr);
            graphics.endFill();

            addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
        }

        public function move():void
        {
            var absx:Number = Math.abs(targetx-x);
            var absy:Number = Math.abs(targety-y);

            if (absx < 1 && absy < 1)
            {
                targetx = randomRange(x - moveRange, x + moveRange);
                targety = randomRange(y - moveRange, y + moveRange);

                if (targetx >= stage.stageWidth)
                {
                    targetx = stage.stageWidth - moveRange;
                }
                else if (targetx <= 0)
                {
                    targetx = moveRange;
                }

                if (targety >= stage.stageHeight)
                {
                    targety = stage.stageHeight - moveRange;
                }
                else if (targety <= 0)
                {
                    targety = moveRange;
                }
            }
            else
            {
                x += (targetx - x) * 0.125;
                y += (targety - y) * 0.125;
            }
        }


        private function onAddedToStage(event:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);

            // position circle on stage
            x = targetx = randomRange(cr, stage.stageWidth - cr);
            y = targety = randomRange(cr, stage.stageHeight - cr);
        }

        private function randomRange(minNum:Number, maxNum:Number):Number
        {
            return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);
        }
    }
}

看起来像这样:

example