ActionScript with version 3.0 is now entirely class based. Before, there was a heavy integration with the timeline and ActionScript - in fact, all classes defined in ActionScript 1 and 2 were defined on the main timeline as timeline code, not as separate class entities. Because of this new restructuring of ActionScript and this separation from the timeline, there has been a substantial change in how ActionScript interacts with the timeline and frame navigation. A specific example revolves around navigating to a new frame within a movie clip and then accessing child objects within that frame. In ActionScript 2, this could easily be achieved with the following:
Code:
// ActionScript 2.0
target.gotoAndStop(10);
target.child._rotation = 90;
Where the child movie clip is a movie clip on frame 10 of the target movie clip. Using target.child._rotation = 90; that child movie clip could be rotated to 90 degrees.
This is no longer possible in ActionScript 3.
At least not as easily. The child objects that exist within a newly navigated frame are not instantiated until after the completion of the frame script. This prevents any unnecessary instantiation of objects in the case that later within that same frame script the object was told to go to a different frame. The downside of this is that no longer will you be able to directly access children in that frame directly after navigating to it as you could before. Now you have to wait until they are instantiated before being able to do anything with them.
The following outlines the order of execution within a frame's time where a target movie clip is navigated to a frame within its timeline where one or more child movie clips exist and would need to be accessed.
- Event.ENTER_FRAME event
- target parents' frame scripts
- target's sibling objects' frame scripts for objects arranged below target
- target frame script [where frame navigation presumably occurs]
- Instantiation of each target's child objects in new frame
- Event.ADDED event for each target's child objects in new frame
- assignment of target's instance name properties for children in new frame
- target's sibling objects' frame scripts for objects arranged above target
- Event.RENDER event (requires call to stage.invalidate())
- Flash draws screen
Note: sibling objects refer to objects with the same parent as the target instance
The main thing to take away from this order is that the instatiation and addition of the child objects within the target instance doesn't occur until after the current frame script of that target completes. This leaves you no way to access those children within that script directly. What you would need to do is access those children through the ADDED or RENDER events. And when using the ADDED event, you still can't reference the children by their instances names as with the AS2 example since the instance name assignment doesn't occur until after the ADDED event(s) complete. For the ADDED events, you would need to check the Event.target property in the event handler and see if the name of that target matches the instance name of the object you wish to access. Using the render event is a little easier but requires a call to stage.invalidate() to even be dispatched.
Using the ADDED Event:
Code:
// ActionScript 3.0
// add an ADDED event handler to the movie clip
// whose frames are being navigated and whose
// child needs to be accessed
target.addEventListener(Event.ADDED, onAdded);
function onAdded(event:Event):void {
// get reference to child from event object
// as child variable of target will not yet be defined
var childRef:MovieClip = event.target as MovieClip;
// check the name of the reference for correct instance name
if (childRef && childRef.name == "child"){
childRef.rotation = 90;
target.removeEventListener(Event.ADDED, onAdded);
}
}
target.gotoAndStop(10);
Using the RENDER Event:
Code:
// ActionScript 3.0
// add an RENDER event handler to the movie clip
// whose frames are being navigated and whose
// child needs to be accessed
target.addEventListener(Event.RENDER, onRender);
function onRender(event:Event):void {
// by the time the RENDER event fires, the child
// clip will be completely defined and accessible
target.child.rotation = 90;
}
// for RENDER to be dispatched, the stage
// has to be invalidated
stage.invalidate();
target.gotoAndStop(2);
Because of this complication, it would be wise to design your applications/Flash movies so that you would not have to access child objects in this manner if possible.