Actionscript 3 Hidden Gem: addFrameScript
So it’s no big secret any more that in Actionscript 3, the MovieClip class has a hidden method that enables developers to add frame scripts at runtime. However, with great power comes great responsability. It would help if this were documented in the Flash docs but it isn’t. If you don’t want your SWF files to crash when using this method you MUST ensure that the playhead is stopped before calling this method. I discovered this by experimenting with when, and what I could do with this method, and yes you can remove any frame scripts added at design-time or run-time (at least with the current version of Flash player). Actually, the playhead does not have to be stopped if you are setting a null frame script.
What I had to do to make using this method easier was to override and provide a few extra operations to MovieClip objects:
private var __playing : Boolean = true;
override public function play () : void
{
if (this.__playing)
return;
this.__playing = true;
super.play();
}
override public function gotoAndPlay (pFrame : Object, pScene : String = null) : void
{
this.__playing = true;
super.gotoAndPlay(pFrame, pScene);
}
override public function stop () : void
{
this.__playing = false;
super.stop();
}
override public function gotoAndStop (pFrame : Object, pScene : String = null) : void
{
this.__playing = false;
super.gotoAndStop(pFrame, pScene);
}
override public function addFrameScript (... pArgs : Array) : void
{
if (pArgs.length != 2)
return;
var frame : int = int(pArgs[0]);
var func : Function = pArgs[1] as Function;
if (this.__playing && func != null)
{
var nextFrame : int = this.currentFrame + 1;
this.stop();
super.addFrameScript(frame, func);
this.gotoAndPlay(nextFrame);
}
else
{
super.addFrameScript(frame, func);
}
}
This works great and my SWF files don’t crash anymore. Also one quick note on the arguments for the method. The accepted arguments are:
addFrameScript( pFrameIndex : int, pActionFunc : Function );
Keep in mind that the frame index is not the same as the frame number, and you can pass a null function to remove a frame script. As noted above, if the function is null then the playhead does not have to be stopped.




Yer code examples would be somewhat more usefull (by becoming readeble) if some proper indenting would be applied. Also some form of syntax highlighting and a wider template blog would be nice. Posting grey left-aligned code in a 400-500 wide column misses the point of displaying nice code.
Macaca
July 4, 2009
Your code doesn’t work.
I
August 17, 2009
Great info! (Don’t listen to those other commenters.)
But I’m still a little curious. What is it about addFrameScript that freezes the program and makes it necessary to override it like that? I see that in the override function you’re using gotoAndPlay() instead of play(). If you try to use play() on a frame that has addFrameScript in it will that freeze the program even if it was stopped when addFrameScript was called? What if you use gotoAndPlay to go to a frame that has addFrameScript?
Scythe
September 21, 2009
My apologies, I had forgotten to add the line where the
__playingfield was declared. Figured that would have been obvious.Scythe: This was a big problem in several instances in a 2D side scrolling game that I helped develop just over a year ago. As stated above, each time we added a framescript dynamically while the playhead was playing we crashed the player. We isolated the cause to the
addFrameScriptmethod. We even tested it with a simple file containing a playing movieclip and added framescripts to it, we got the same problems.Now I can’t recall the exact player version but I know it was one of the earlier versions of player 9.
One other issue we found with
addFrameScriptwas that the calls tended to fail and even be completely erased with components on the timeline. That is to say that prior calls toaddFrameScriptwith valid function pointers, before any instances were added to the timeline, the functions wouldn’t execute at all with components on the timeline. So the bottom line is that (for player 9.x anyways) it’s best to just use components on the timeline oraddFrameScriptsbut not both at the same time.With player 10.x is out now I’ve tested this again and it seems that there has no more problems. I was able to add frame scripts while the playhead was playing and while components were on the timeline.
As for the formatting problems, sorry about that, but I just verified again that the code does in fact work as posted. Just it was missing the
__playingfield.The code now has the proper formatting and the missing field.
Darren Schnare
September 27, 2009