如何立即获取不同帧的MovieClip的宽度?

时间:2013-05-27 17:53:35

标签: actionscript-3 flash

有没有办法在不同的帧上获得MovieClip(有一个名字)的宽度?我曾尝试使用 .width .getBounds(null).width ,但是,它们都只会给我当前帧的宽度。我曾尝试做 gotoAndStop(frameiwant),但至少在下一帧之前信息似乎不正确

我想立即获得框架的宽度,所以我不必等到宽度的下一帧。

4 个答案:

答案 0 :(得分:4)

我能想到这样做的唯一方法是在项目中有一个初始阶段:

  1. 浏览时间轴中的所有帧。创建一个对象,该对象将保存有关该帧中子项的信息。它可以被称为Frame
  2. 迭代添加到该帧中的舞台的所有子项,并添加描述该子项的定义对象。您可以根据需要进行描述。我们可以将此类称为ObjectDefintion
  3. 这个过程的缺点是你需要等待@Larusso在他的回答中指出的FRAME_CONSTRUCTED事件。这意味着框架实际上必须在您能够获得有关其子项的信息之前完成渲染,这当然意味着您必须在此阶段中通过并渲染时间轴中的每个帧。你可以做的只是缓解这个问题,将frameRate设置为高,然后在评估完所有帧时将其设置回来。

    我已经设置了它并且运行良好 - 我会粘贴每个类并尝试解释它们的作用。

    因此,对于您的文档类(或任何一个MovieClip包含您想要查看的帧),我有这个:

    public class Main extends MovieClip
    {
    
        private var _userFrameRate:int;
        private var _frames:Vector.<Frame> = new <Frame>[];
    
    
        public function Main()
        {
            _userFrameRate = stage.frameRate;
            stage.frameRate = 120;
    
            addEventListener(Event.FRAME_CONSTRUCTED, _assess);
        }
    
    
        public function getFrame(index:int):Frame
        {
            return _frames[index - 1];
        }
    
    
        private function _assess(e:Event):void
        {
            var frame:Frame = new Frame(this);
            _frames.push(frame);
    
            if(currentFrame === totalFrames)
            {
                removeEventListener(Event.FRAME_CONSTRUCTED, _assess);
                gotoAndStop(1);
                stage.frameRate = _userFrameRate;
    
                ready();
            }
    
            else play();
        }
    
    
        public function ready():void
        {
            // Start here.
    
            // There is a MovieClip on frame 10 with the instance name 'test'.
            // We can get the width of it like this.
            trace( getFrame(10).define("test").property("width") );
        }
    
    }
    

    这基本上初始化了我们将在MovieClip中的每个帧上运行并评估其子节点的阶段。 ready()方法用作代码后评估的入口点。

    接下来我们有Frame类,用于保存与框架相关的子项信息:

    public class Frame
    {
    
        private var _main:Main;
        private var _content:Object = {};
    
    
        public function Frame(main:Main)
        {
            _main = main;
            update();
        }
    
    
        public function update():void
        {
            _content = {};
            for(var i:int = 0; i < _main.numChildren; i++)
            {
                var target:DisplayObject = _main.getChildAt(i);
    
                // This will be explained below.
                var definition:ObjectDefinition = new ObjectDefinition(target, "x", "y", "width", "height");
    
                _content[target.name] = definition;
            }
        }
    
    
        public function define(name:String):ObjectDefinition
        {
            return _content[name];
        }
    
    }
    

    这非常简单 - 你给它Main的引用,以便它可以检查每帧中存在的子项。

    ObjectDefinition类也非常简单,纯粹作为数据的存储库,您想要跟踪框架的每个子项:

    public class ObjectDefinition
    {
    
        private var _definition:Object = {};
    
    
        public function ObjectDefinition(target:DisplayObject, ...properties)
        {
            for each(var i:String in properties)
            {
                _definition[i] = target[i];
            }
        }
    
    
        public function property(property:String):*
        {
            return _definition[property];
        }
    
    }
    

    您会注意到构造函数接受将要定义的目标DisplayObject,以及您希望作为字符串跟踪的任何数量的属性(请参阅上面Frame中的实现)。

    完成后,您可以将方法Main.getFrame()Frame.define()ObjectDefinition.property()链接起来,以获取整个时间轴中将存在的子项的属性。例如,如果您在第15帧上有一个实例名称为square的MovieClip,并且您希望获得其宽度和高度,则可以在.ready()内执行此操作,如下所示:

    var square:ObjectDefinition = getFrame(15).define("square");
    trace(square.property("width"), square.property("height"));
    

    当然这个过程并不理想 - 但不幸的是,这是我能看到你想要达到的目标的唯一方法。

答案 1 :(得分:0)

在您要求提供信息之前,您必须先听取特定事件。

clip.addEventListener(Event.FRAME_CONSTRUCTED, frameReadyHandler);
clip.gotoAndStop(frame);

function frameReadyHandler(event:Event):void
{
    clip.removeEventListener(Event.FRAME_CONSTRUCTED, frameReadyHandler);
    var width = clip.width;
}

Frame构造的事件是分派的几个事件中的第一个。它会在帧脚本执行之前立即调度。您还可以等待输入框架事件。

答案 2 :(得分:0)

您可以添加1毫秒的事件侦听器,并测试您存储的previousWidth是否不同。如果是的话,你去吧。如果没有,它可能会听同一帧。

一个1毫秒的计时器并不是一件大事,如果你不需要它就停止它,如果你这样做就恢复它,否则,让它继续运行。当它发生变化时,发送一个事件或任何需要发生的事情。

答案 3 :(得分:0)

如果你知道MovieClip的最大尺寸,你可以试试这个:

// Create movie clip
var movie :MovieClip = new MovieClipWith3Frames();

// Move to second frame
movie.gotoAndStop(2);

// Create bitmap witch magenta background
var bd :BitmapData = new BitmapData(200, 200, false, 0xFF00FF);

// Draw second frame
bd.draw(movie);

// Found the bounds of shape
var movieBounds:Rectangle = bd.getColorBoundsRect(0xFFFFFF, 0xFF00FF, false);

trace(movieBounds); // (x=42, y=15, w=32, h=33)