The only way I could think of is to make the initial stage in your project, which will be:
- Run all frames on the timeline. Create an object that will store information about the children in this frame. It can be called
Frame . - Iterate over all the children that are added to the scene in this frame, and add the definition object that this child describes. The description can be as basic or as extensive as you need. We can call this class a
ObjectDefintion .
The disadvantage of this process is that you need to wait for the FRAME_CONSTRUCTED event, for example @Larusso, indicated in its answer. This means that the frame actually needs to finish rendering before you can get information about its children, which of course means that you need to go through and display each individual frame on your timeline at this point. All you can really do to mitigate this problem is set the frameRate to something high, and then set it when you finish evaluating all frames.
I installed this and it works well - I will insert each class and try to explain what they do.
So, for your document class (or depending on which MovieClip contains the frames you want to look at), I have the following:
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 {
This basically initializes the phase in which we will run each frame in MovieClip and evaluate its children. The ready() method is used as an entry point for subsequent code evaluation.
Next, we have the Frame class, which serves to store information about the child elements associated with the 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);
It's pretty simple - you give it a link to Main so that it can check the children that exist inside it in every frame.
The ObjectDefinition class ObjectDefinition also quite simple, acting solely as a repository of data that you want to track on each child of the frame:
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]; } }
You will notice that the constructor accepts the target DisplayObject to be defined, as well as any number of properties that you want to track as strings (see above in Frame for implementation).
Once completed, you can link the Main.getFrame() , Frame.define() and ObjectDefinition.property() to get the properties of the children that will exist throughout the timeline. For example, if you have a MovieClip with the instance name square in frame 15, and you want to get its width and height, you can do it in .ready() as follows:
var square:ObjectDefinition = getFrame(15).define("square"); trace(square.property("width"), square.property("height"));
Of course, this process is not ideal, but, unfortunately, this is the only way to see that what you want to achieve is possible.