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

发布于 2024-12-17 22:57:07 字数 1868 浏览 4 评论 0原文

我试图找到一种很好的方法来同时使用 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();

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

I'm trying to find a good way to use TweenMax and flash's drawing class together, but it always bogs down and crashes the flash player, and I can't really figure out what's going wrong. Really all I want to do is make sure that when two (or more) circles, connected by a line, move, that the line between them follows. This is my code:

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

Is there a better way to do this? Should I not be using a tweening library?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无法回应 2024-12-24 22:57:08

因为 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

because mheavers asked me, i put together a little example using an ENTER_FRAME listener to animate the circles manually.

i got two classes:

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

and another one for the circle:

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

looks sth like this:

example

记忆で 2024-12-24 22:57:07

假设您取消注释 TweenMax 行,函数 drawLine() 调用 moveCircle()...这将为每个圆添加一个补间,这将调用 drawLine( ) 再次 - 一切都会重复。我猜它增加了大量*的听众和补间,导致崩溃。您应该添加一个检查,以防止添加其他补间,而该圆仍有一个补间正在运行。

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

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


编辑:
* 我喜欢数字。假设帧速率为每秒 24 帧,您确实会得到相当多的补间。呈指数增长。初始化时 1 个补间,第一帧中 2 个补间,第二帧中 4 个,依此类推。当第一个补间完成时(如果它在崩溃之前完成),您将运行大量 2^24-1 补间。 16777215 补间。对于每个圆。

但现在说真的,要解决这个问题,您可以使用 TweenMax.isTweening(circleArray[i]) 来检查是否已经有一个补间正在运行。我认为drawLine不应该调用moveCircle。函数 moveCircle 现在应该只调用一次,以启动补间 - 或者如果您希望它循环,则每次补间完成时 (onComplete)。

Assuming you uncomment that TweenMax line, the function drawLine() calls moveCircle()... which is adding a tween for each circle, that will call drawLine() again - and everything repeats. I guess it's adding tons* of listeners and tweens, resulting in a crash. You should add a check, that prevents the other tweens from being added, while there is a tween still running for that circle.

Also, lineCanvas.graphics.clear(); should be moved before the loop, otherwise it would clear lines drawn for the other circles, if there are any.

Tweening libraries are good, you should use one if you can. They help very much even with simple tweening task.


Edit:
* I like numbers. Assuming a frame rate of 24 frames per second, you really get quite a lot tweens there. Growing exponential. 1 tween when initializing, 2 tweens in the first frame, 4 in the second, and so on. When the first tween finishes (if it were doing so before the crash) you'd have a nice number of 2^24-1 tweens running. 16777215 tweens. For each circle.

But seriously now, to fix this, you could use TweenMax.isTweening(circleArray[i]) to check if there is already a tween running. I think drawLine shouldn't call moveCircle. The function moveCircle should now only be called once, to start the tween - or if you want it to loop, every time a tween is complete (onComplete).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文