Actionscript 3 Hidden Gem: addFrameScript

Posted on July 28, 2008. Filed under: Actionscript 3, Programming |

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.

Make a Comment

Make a Comment: ( 4 so far )

blockquote and a tags work here.

4 Responses to “Actionscript 3 Hidden Gem: addFrameScript”

RSS Feed for GDTech Comments RSS Feed

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.

Your code doesn’t work.

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?

My apologies, I had forgotten to add the line where the __playing field 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 addFrameScript method. 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 addFrameScript was that the calls tended to fail and even be completely erased with components on the timeline. That is to say that prior calls to addFrameScript with 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 or addFrameScripts but 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 __playing field.

The code now has the proper formatting and the missing field.


Where's The Comment Form?

Liked it here?
Why not try sites on the blogroll...