Tutorials, extensions, and source files for ActionScript, Flash, and other Adobe products.

 

Flash Frequently Asked Questions (FAQ)

Why does my preloader start at 40% (or some other unnecessarily high value)?

The Quick: Items in your library such as movie clips and sounds set to be exported for ActionScript (exported in first frame) are loaded before your preloader is loaded even if your preloader is placed on the first frame of your movie.

The Details: When a Flash movie loads into the Flash player, it loads in a progressive manner that loads all content at the beginning of the movie before any content later on in the movie. Doing this allows for movie playback to begin prior to the entire movie having been fully downloaded. Flash knows how to do this because everything on the timeline is static and doesn't change. Just by looking at the timeline, you can tell which content comes first (which is loaded first) and which follows it (and loads later). When dealing with the use of library items through ActionScript, there's no real way to tell just when exactly those items will need to be addressed. It could be the first frame of the Flash movie or it could be the last. Because the use of ActionScript allows for such usage to be dynamic, Flash has no way of knowing when to load the library items utilized by ActionScript. As a result, by default, Flash loads all library items exported for Actionscript in the first frame, and actually this means at the very start of the first frame prior to anything you actually use in the first frame, such as your preloader.

Now, for these library items, you can disable the option to have them load in frame 1 (as of Flash MX). However, in doing so, you run into another problem.

In order for Flash to keep published swf files as small as possible, not all library items in the fla are actually included in the swf. Only those that are used are included. This includes all library items used on the movie's timeline as well as any that may not be on the timeline but were instructed to load in frame 1. If you uncheck the Export in first frame option and that particular library item is not somewhere on the timeline of the Flash movie, it will not be included in the swf when its created thereby making it completely inaccessible for whatever you had intended to use it for.

There's one fairly obvious solution to this problem; uncheck the Export in first frame option for each exported library item used in this manner and place each somewhere on the timeline after your preloader. Despite the fact that the library items are not loaded in the first frame, they will at least still be included and thereby usable in the published swf. From there, its just a matter of making sure that you include them on the timeline before you attempt to use them. It's recommended you put your preloader on frame 1, all ActionScript-exported library items on frame 2, and begin your actual Flash movie at frame 3 (going directly to frame 3 when the preloader is complete).

Alternatively, to bypass all of the above complications, you can just use a separate swf that consists only of a preloader to load your main movie into a new level of that preloader swf. This will also make it easy to use the same preloader swf to load multiple other swfs.

Update: For more details and examples see the Flash Preloader Tutorial.

Why won't gotoAndPlay() work with scenes when used in movie clips?

The Quick: Scenes are junk; don't use gotoAndPlay("sceneName"), instead create a frame label in the first frame (or wherever needed) and use _root.gotoAndPlay("labelName") to go to that frame.

The Details: Scenes can be a bit of nasty in Flash. They usually work well enough for animators who work pretty much exclusively on the main timeline, but for anyone using any decent amount of ActionScript or level or depth in a Flash movie they are usually (and should be) avoided. The main problem with scenes is that they don't really exist once a Flash movie is published into a swf file. Scenes in the fla are actually concatenated to form one long timeline that represents the main timeline, _root.

The only remnants of scenes in a published swf are hooks left in the main timeline (_root) for gotoAndPlay and gotoAndStop commands to recognize scene navigation if used there. This includes commands like gotoAndPlay("sceneName", 1); which navigates to and plays the first frame in the scene named "sceneName." Note that this is only for the _root timeline. That means that if gotoAndPlay or gotoAndStop is used anywhere other than _root, Flash will not know well enough to suspect that the navigation may be for scene navigation and, instead, interpret navigation as frame or label navigation.

Which is where the problem lies: gotoAndPlay (and gotoAndStop) statements inside movie clips that are meant to control the main timeline. First and foremost you should know that to use a gotoAndPlay function (or any function) for a timeline other than the one you are in, a prefix to that function is needed. In the case of the main timeline, to run gotoAndPlay statements for it you simply run gotoAndPlay off of _root.
_root.gotoAndPlay(value);

This will run gotoAndPlay for the main _root timeline, but it does not solve the problem of the missing scene references. This is a little bit more of a problem since there is no way from within your movie clip that you're getting them out of the main timeline. Specifying _root for gotoAndPlay won't do it. They're simply unavailable.

However, since gotoAndPlay still works for frame numbers and frame labels, you can use those to navigate _root where you want it to be. There's a problem in using frame numbers, though, since in the fla each scene shows its frame numbers starting at 1 through to the scene's last frame, but in the swf, those values are changed for all scenes but the first since each scene is turned into one large scene. What is frame 5 in Scene 2 instead becomes frame 5 plus the total number of frames in each scene before it. That means it can be a chore to figure out what frame it is you need to go to exactly. And what if all of a sudden you need to add 5 frames to the first scene? That could completely offset all gotoAndPlay statements using specific frame values for all following scenes. That leaves us with frame labels which seem to do the job nicely. Despite the number of frames in any scene, frame labels are always in the place you defined them.

So, when you need to navigate to a new scene from within a movie clip, all you need to do is use gotoAndPlay for _root specifying a frame label you placed in the scene you want to navigate to. If you want to play the first frame of Scene 2, create a frame label in frame 1 of Scene 2 and use gotoAndPlay to go to that label.

_root.gotoAndPlay("secondScene");

My class extends or inherits from MovieClip. When I make an instance of it in Flash, why doesn't it show up on the stage?

The Quick: Instantiation of MovieClip instances (and subclasses of MovieClip) are are not handled through the new keyword. Instead, instantiation is automatic as a result of the movie clip representing that class being created in your scene, either through placement on the timeline or through attachMovie()/duplicateMovieClip().

The Details: The way Flash handles class instances with movie clips is a little non-intuitive and contradicts how classes and visual elements work in other programming languages such as Java. Because MovieClip instances have this inherent connection with a visual element (a movie clip) within the Flash document, basic class instantiation through the use of the new keyword won't cut it since creating new instances in this manner only creates instances in memory that have no association with the timeline other than a variable returned from the constructor used to access the object created. Creating movie clips requires another level of instantiation that, through code, is handled through attachMovie (or duplicateMovieClip though this assumes an instance already exists so we'll focus on attachMovie). Flash doesn't know any better to be able to do this through the use of new. Why this is, is in part a result of the requirements for screen elements like movie clip symbols. Movie clip symbols need to have a unique identifying instance name, need to exist in a single (_parent) timeline, and have in a unique numeric depth within that timeline. These specifics are not something that can be easily facilitated in a class definition, at least not as Flash sees things. Classes, to Flash, are just for property and method definitions--code stuff, not visual stuff. In fact the MovieClip class is just that, code movie clips use. You can't instantiate actual movie clips using new MovieClip; That just creates a generic object in memory (well, technically a MovieClip instance) that has access to all MovieClip class members but is not physically associated with anything on the timeline at all. To physically create visual elements within a timeline, you would use attachMovie.

Now, the trick here is how you then are able to create classes that represent these visual movie clip symbols. Instead of creating a class instance that creates the symbol, which, as you know, doesn't happen, you create the symbol first (attachMovie) which then creates the instance, or rather, instantiates itself to be an instance of the class that's associated with that symbol. It's a bass-ackwards way of instantiation but its Flash's way of getting it done. So what may have been:

var myInstance = new MovieClipSubClass(); // incorrect

would now be:

var myInstance = timeline.attachMovie("SymbolLinkageID", "myInstanceName", depth); // correct

Where timeline is the timeline where the movie clip is to be attached and "SymbolLinkageID" is the linkage ID set for the movie clip symbol in the library. Make sure that you have associated the movie clip symbol with your class with Object.registerClass or through the linkage properties dialog (MX 2004). Note that movie clips created with createEmptyMovieClip cannot be associated with ActionScript classes. However, Flash MX 2004 will automatically create empty movie clip symbols in a published swf for each of your classes with the linkage ID "__Packages.[Full Class Name]" (as it is used to define the class). So, if you want to use your class with an empty movie clip, you can use that automatic library symbol without worrying about creating your own. You will need to associate the library symbol with your class using Object.registerClass, though, since that association is not inherent.

There is one fairly major caveat to this method of MovieClip class instantiation. What that is, is attachMovie doesn't support the including of constructor parameters. When a MovieClip instance's constructor is run, it is run automatically and without arguments.

There are a couple of ways to handle this limitation. One thing you can do is assign values to the movie clip through the initObject parameter in attachMovie. All properties in an initObject object, when passed into attachMovie, are copied into the resulting instance. This happens prior to the constructor call so those values will be accessible from within the constructor.

var initObject = {propertyA:value1, propertyB:value2};

var myInstance = timeline.attachMovie("MovieClipSubClassID", "myInstance", depth, initObject);

The problem with an initObject is that there is no regulation of the values. When passed, they are added to the resulting movie clip no matter what. In a constructor, you get to delegate the passed values as needed. Also, when using an initObject, typing and class rules for ActionScript 2.0 is ignored. The compiler pretty much ignores anything in the initObject and it will go through regardless.

A more popular means of overcoming the lack of a valid constructor for MovieClip instantiation is the use of an init method. The init method is simply a method created to take over the tasks that would otherwise be handled by the class constructor. As a method, you are able to supply it with any arguments you need. Using an init method directly after attachMovie will let you have your constructor, just in the form of a method named init. For example (AS 2.0):

class MyClass extends MovieClip {

	function MyClass(){

		// no arguments passed

	}

	public function init(value1:Number, value2:Number):MyClass{

		// use value1 and value2 as you would in the constructor

		return this;

	}

}

Notice the use of return this; returning the class instance. This lets you use the init method directly after a call to attachMovie and have it still return the instance created.

var myInstance = timeline.attachMovie("MovieClipSubClassID", "myInstance", depth).init(value1, value2);

It is also not uncommon to have a static create method in your class to generate movie clip instances for you. Having such a method lets you avoid any confustion that might result in using attachMovie as well as provides you a means to pass all arguments for instantiation into one function call as opposed to 2, which is what you get with attachMovie + init. For example:

class MyClass extends MovieClip {

	static var symbolName:String = "MyClassLinkageID";

	static function create(timeline:MovieClip, name:String, value1:Number, value2:Number):MyClass{

		var instance = timeline.attachMovie(symbolName, name, timeline.getNextHighestDepth());

		// use value1 and value2 as you would in the constructor only on 'instance' and not 'this'

		return instance;

	}

	function MyClass(){

		// no arguments passed

	}

}

Instances of MyClass are then created using:

var myMov:MyClass = MyClass.create(this, "myMov", 5, 10);

Note that a depth parameter was omitted in favor of having the new instance's depth controlled from within the create method. It could have just as well been passed with the others of the values. The same also applies to the movie clip linkage. However, if you plan to use more than one movie clip symbol, you would need to make sure you use Object.registerClass to associate the class to each symbol before using attachMovie.

What happened to my variables and why aren't my functions working (e.g. onLoad) after loadMovie?

The Quick: When new content (swf or jpg) is loaded into a level or movie clip using loadMovie(), the level or movie clip is erased of all definitions--all functions and variables.

The Details: Basically what happens is Flash completely clears or replaces an existing level or movie clip in order to make way for that which is being loaded as a result of the loadMovie command. Movie clips will actually retain their size and location and primary properties while levels are completely replaced and set back to their default location (0,0). In either case, anything you define in a level or movie clip will be deleted thanks to loadMovie. This includes any event handlers like onRelease which you've added to interact with the soon to be loaded content. The only exception to this is script placed directly on a movie clip in the form of on() or onClipEvent()events (applicable to movie clips only) as they inherent of the actual movie clip symbol and not something Flash interprets as an assignment within it. However, these kinds of scripts are now deprecated.

For users publishing to Flash Player 7 or above, one option is to use a MovieClipLoader instance to manage the loading of external content in this manner. For Flash Player 6 and below, your basic progress checks comparing getBytesLoaded and getBytesTotal serve as a solution (assigning your variables and functions when both getBytesLoaded and getBytesTotal are valid values and they are equal).

An alternate solution is, instead of using the loadMovie command on the movie clip containing your functions or variables, use it with an empty movie clip placed inside of that movie clip. That will restrict the problems associated with loading to that empty movie clip which would have no variables or functions associated with it.

this.createEmptyMovieClip("loader", 0);

this.loader.createEmptyMovieClip("content", 0);

this.loader.content.loadMovie("myMovie.swf");

this.loader.onRelease = function(){

	trace("you just clicked the loaded movie");

}

Why aren't my loaded variables/XML accessible after I used LoadVars.load()/XML.load()?

The Quick: Anything you load from external source will take time to make it into the Flash player and ActionScript does not wait for loaded content to be received before it continues executing. You will need to use onLoad instead.

The Details: When you use the load command from either a LoadVars or XML instance (or really anything that loads anything from an external source) Flash takes the URL passed and begins loading it in the background. As it loads, Flash will continue running ActionScript as normal meaning that, chances are, if you try to access any variables loaded from a load command directly after the load command, they will not be accessible to you as they are still in the process of being loaded. Only when they have finished loading will they be accessible and that could be many frames after the initial load command. In fact, there's no way to tell given various speeds of people's internet connections. So when do you know when something is loaded and your variables are accessible? You use an onLoad event handler (function) assigned to your LoadVars or XML instance. This function will automatically be called when that which was loaded with a load command has successfully (or not) made it to the Flash player.

var loader = new LoadVars();

loader.load(myVariables);

trace(loader.aLoadedVariable); // incorrect, aLoadedVariable hasn't loaded yet



loader.onLoad = function(successful){

	if (successful){

		trace(loader.aLoadedVariable); // correct, aLoadedVariable loaded successfully

	}else{

		trace("Error in loading myVariables");

	}

}

trace(loader.aLoadedVariable); // still not loaded, this script is quick to run, loading is not

Why doesn't my movie work when publishing for Flash 7 when it does when I publish for Flash 6?

The Quick: Changes between the way the two versions handle ActionScript have changed. Code that works in Flash 6 may not work in Flash 7 if it doesn't adhere to the new rules.

The Details: Before Flash MX (6) there was Flash 5 and ActionScript code was pretty sloppy. When Flash MX came out, some things changed involving how ActionScript work and some scripts broke (namely resulting from differences in variable scope). People fixed their code and as a result became scripts became less sloppy. Enter the post Flash MX format, Flash MX 2004 (7). Again, things have changed and again, as a result, code will become less sloppy still. Here are some of the differences that come with using Flash 7 as a publish format:

1. Case sensitivity
In a Flash 7 swf, all variables and keywords are case sensitive. This means that myvariable is not the same as myVariable. If used (as variables) Flash will interpret each to have their own separate values. This also means that attachmovie() will no longer attach a movie from your library onto the screen. The correct command is attachMovie()with a capital M.

If you've been a sloppy coder in the past, or just not keeping correct capitalization, this may be a problem. Now you'll have to be sure to maintain consistency with capitalization. With Flash objects and methods, color coding can help. With your own variables, you'll just have to keep to your guns and be consistent.

2. Undefined variable values have changed
When you use a variable that has not been previously defined somewhere in your script, Flash needs to assume a certain default value for that variable. This value is based on the context of where its first used; is it being used as a number? as a string? With Flash 6, this definition is 0 if used as a number and an empty string (""), even though technically the variable is still considered undefined. When using Flash 7, these default values have changed. Now, if an undefined variable is used as a number, a NaN is given; if as a string, the string "undefined" is given.

var name, job;

name = "George";

trace(name+" works for "+job); // F6: "George works for ", F7: "George works for undefined"



var value;

value++;

trace(value); // F6: 1,  F7: NaN

3. String boolean value has changed
Now with Flash 7 strings, as long as they aren't empty, they have a boolean value of true. This means that when they are seen in a true/false situation, as long as the string has some value, it is seen as being true. This includes strings like "0". In Flash 6, strings are first converted to a number and then evaluated to being if that number was non-zero and false if not (i.e. if 0). Flash 6 will interpret "0" as being false; Flash 7 will not as it is not empty. To Flash 6 any non-numeric string is false. To Flash 7, as long as it has length, no matter if its numeric or not, it's true. Look at the following chart for examples.

  Flash <= 6 Flash 7+
"" false false
"0" false true
"1" true true
"text" false true

4. Removed array lengthening with string indexing
Though you may have never known it or even made us of it, with Flash 6, you could extend the length of an array if you tried assigning a value to an index of that array outside of its length if using a string that was not a specific array index but could be parsed into one (i.e. a string that when used with parseInt would result in a number). The string "5tuna", for example, is not fully numeric so cannot specify a specific index of an array. However, when parsed into a number, that value becomes 5. If you tried to assign the index "5tuna" of an array with a length less than 6 in Flash 6, that array's length would then reach out to be 6 to account for the supposed index (even though, oddly enough, no actual value would be assigned to it). Now, when publishing your swf to Flash 7, that is not possible. Using strictly numeric strings, however, is still acceptable and will continue to work fine.

myList = new Array(2);

trace(myList.length); // 2

trace(parseInt("5tuna")); // 5

myList["5tuna"] = "anything";

								

trace(myList.length); // F6: 6, F7: 2

trace(myList[5]); // undefined

Can I use a variable to reference an instance name or another variable?

The Quick: Yes. you can do this using eval() or array/bracket ([]) syntax.

The Details: The eval function is a top level function in Flash that creates valid variable references based on a string representation of that reference. This lets you evaluate targeted paths from a string. Note that eval in Flash is used only for evaluating references in this manner; it does not evaluate or execute ActionScript code like eval in JavaScript. The following two lines of code refer to the same ball movie clip.

var reference = _root.container.ball;

var reference2 = eval("_root.container.ball");

Since eval accepts any string, you can use variables to define your string so that will eval reference an instance name or variables dynamically. Consider the following: you have 5 ball movie clips in _root of your movie named ball1, ball2, etc., and you want to give them all an alpha value of 50. You could list them all out individually, or you can use a loop and reference them each with a variable like so:

for (var i = 1; i <= 5; i++){

	var currball = eval("_root.ball" + i);

	currball._alpha = 50;

}

Be aware that eval also only generates references, it cannot be used to define them. In other words, you cannot assign a value to equal an evaluated reference (Flash will usually give an error stating that eval cannot be used on the left side of an =).

Bracket ([]) syntax evaluates a string it contains and resolves a variable reference for an object preceding the first [. So _root["ball"]; is the same as _root.ball; and _root["ball"+1]; is the same as _root.ball1; This will let you dynamically reference instance names and variables much like eval.

Arrays rely on this method of variable resolution since array values are stored in variables whose names are numbers. Normally numbers are not allowed as variable names because dot syntax cannot properly resolve variables names starting with numbers as it assumes it to be a number value, i.e. _root.3something; screws up because Flash gets to the 3 and thinks the number 3, not a variable name starting with 3. However, this naming restriction can be averted using bracket syntax, _root["3something"]; and in arrays' cases, is required, someArray[3]. Note that bracket contents do not have to be strings, though a string representation of the contents is used to resolve the variable--this through the toString() method.

All variable types in Flash have a toString method which determines what its value looks like as a string. For numbers, its just a value conversion of number to string, visually not really changing at all. Arrays show a string listing of their values separated by commas and for basic objects, you've probably seen its default as "[object Object]" in a trace in Flash. Bracket syntax uses this string representation for evaluation so someArray[3]; is seen as someArray[String(3)]; or someArray["3"]; You can use this to your advantage with other variable types like generic objects. See the following:

myNameObject = new Object();

myNameObject.toString = function(){

        return "value";

}

myValueObject = new Object();

myValueObject.value = 3;

trace(myValueObject[myNameObject]); // traces 3

The myNameObject variable was used to reference the value property of the myValueObject. In the brackets, Flash evaluated myNameObject into its string representation which was customized for myNameObject to output value giving myValueObject["value"]; That then was converted into a variable reference of myValueObject.value; giving the final trace of 3. Consider the following:

myGenericObject = new Object();

myOtherGenericObject = new Object();



myValueObject = new Object();

myValueObject["[object Object]"] = 6;



trace(myValueObject[myGenericObject]); // traces 6

trace(myValueObject[myOtherGenericObject]); // traces 6

Here the myValueObject was given a property called "[object Object]"--something only possible using bracket syntax. Then, two separate generic objects can be used to retrieve that value since their default string representation results in "[object Object]"

Now, an important thing to understand here is that this is for a single variable name in a single object. Brackets don't evaluate paths. So, a "." does not change scope, it becomes part of the variable name. Example:

myValueObject = new Object();

myValueObject.container = new Object();

myValueObject.container.value = 9;

trace(myValueObject["container.value"]) // traces undefined

That traces undefined because the brackets evaluates the string into a single variable name to be resolved in myValueObject, not a path from that object. So myValueObject["container.value"]; checks for the variable named "container.value" in myValueObject, something that doesn't exist. A container variable exists, and it has its own value variable, but a "container.value" variable doesn't exist directly in myValueObject.

Why does a function created in a loop always use results from the last iteration of the loop?

The Quick: Functions created in loops retain access to the exact same increment variable used in the looping instead of getting a copy of their own meaning, by the time they are called, they will be seeing the value of that variable as it was at the end of the loop. You need to explicitly define that value for each function individually and use that copy as a reference.

The Details: One of the features of functions in Flash is that they have access to the scopes of the blocks in which they are created. When you create a function in a loop, it has access to all the variables used in that loop. Looping many times you can define multiple functions at once. For example:

functions = []

for (var i=0; i<3; i++){

	functions[i] = function(){

		trace(i);

	}

}

functions[0](); // traces 3

functions[1](); // traces 3

functions[2](); // traces 3

Each function has access to the i variable because it was defined in a scope where the i variable existed. As you run those functions though, as you can see, each one traces the last value of i, not the value of i when the function was created. This is as expected since the value being traced is the value of the i variable at the time of the function call. Since each function is being called after the loop, when i has been incremented 3 times, you're seeing a value of 3. The value of i is not "baked" into the function during definiton, just as an onEnterFrame event you defined checking the _x value of a movie clip isn't going to only provide that value as it was at the time the function was defined.

To get around this, you need to define a new, unique variable to represent that value at the time of function creation and have the function reference that value. Consider the following example using an onRelease for a group of buttons:

// 3 buttons: button1, button2, and button3

var curr_button;

for (var i=1; i<=3; i++){

	curr_button = this["button"+i];

	curr_button.num = i;

	curr_button.onRelease = function(){

		trace(i); // would trace 4 for each button

		trace(this.num); // the value of i when the onRelease was created

	}

}

By defining a unique variable num in the button using the function, the value of i can be stored and correctly referenced when the function is called.

Why is one of my functions causing another one to stop working (when using onEnterFrame)?

The Quick: Movie clips are allowed only one onEnterFrame function. If you have two functions which make use of onEnterFrame by setting it for your movie clip, when ever one is used, it will overwrite the last onEnterFrame assigned killing previous assignments.

The Details: Flash MX introduced the onEnterFrame event callback which enabled users to dynamically assign enterFrame events for movie clips. One stipulation in handling this event (which is common among all single object callbacks) is that you can have only one per movie clip. Some people, however, when making functions to be used on movie clips take advantage of assigning an onEnterFrame event handler without consideration that it may be needed for something else. Consider the two following methods which both assign an onEnterFrame for the movie clip in which they are used on:

myMovieClip.moveRight = function(){

	this.onEnterFrame = function(){

		this._x++;

	}

}

// usage:

myMovieClip.moveRight(); // starts moving clip right every frame



myMovieClip.moveDown = function(){

	this.onEnterFrame = function(){

		this._y++;

	}

}

// usage:

myMovieClip.moveDown(); // starts moving clip down every frame

Now lets say you want to move your movie clip both right and down. You would think you'd just be able to call both moveRight and moveDown. This, however, won't work since that last one you call will overwrite the onEnterFrame used by the other.

myMovieClip.moveRight();

myMovieClip.moveDown();

The above will only cause the myMovieClip movie clip to move down since the onEnterFrame set by moveRight was overwritten by the onEnterFrame set by moveDown.

Because of this behavior, it's generally a bad idea to define onEnterFrame event handlers in functions like those above. Instead, consider some alternatives.

1. Create functions to be used within an onEnterFrame event
Instead of creating functions that set the onEnterFrame event of a movie clip to perform actions, set up the function itself to be used in a single onEnterFrame that you define. This way, if you want to use many functions that operate in onEnterFrame events, you can do so by calling as many as needed within that single, more controlled onEnterFrame event.

myMovieClip.moveRight = function(){

	this._x++;

}

myMovieClip.moveDown = function(){

	this._y++;

}



myMovieClip.onEnterFrame = function(){

	this.moveRight();

	this.moveDown();

}

2. Use an array to allow for the inclusion of any number of functions to be called in an onEnterFrame
Lets say that you don't know what or how many functions will need to use the onEnterFrame for your movie clip. You can't very well manually place them in the movie clip's onEnterFrame if you're not sure. What you can do instead is store these functions dynamically in an array. This array can then be cycled through in the movie clip's onEnterFrame event where each function inside is called.

myMovieClip.moveRight = function(){

	this._x++;

}

myMovieClip.moveDown = function(){

	this._y++;

}



myMovieclip.enterFrames = new Array();

myMovieclip.onEnterFrame = function(){

	for (var i = 0; i < this.enterFrames.length; i++){

		this.enterFrames[i].call(this);

	}

}

myMovieclip.enterFrames.push(myMovieclip.moveRight);

myMovieclip.enterFrames.push(myMovieclip.moveDown);

You just need to make sure that the movie clip and its onEnterFrame is set up to handle functions in this manner (something which may be difficult to enforce when sharing code).

3. Create new temporary empty movie clips to provide a unique onEnterFrame
If you still want your functions to run their own onEnterFrame events, you can do so by utilizing another movie clips onEnterFrame to prevent the need of overwriting the target movie clip's onEnterFrame. The easiest way to find another movie clip for this purpose is to make it yourself using createEmptyMovieClip().

myMovieClip.moveRight = function(){

	this.createEmptyMovieClip("moveRightEnterFrame", 1000);

	this.moveRightEnterFrame.onEnterFrame = function(){

		this._parent._x++;

	}

}

myMovieClip.moveDown = function(){

	this.createEmptyMovieClip("moveDownEnterFrame", 1001);

	this.moveDownEnterFrame.onEnterFrame = function(){

		this._parent_y++;

	}

}



myMovieClip.moveRight();

myMovieClip.moveDown();

One thing you have to be careful of is that you have a suitable depth to place the empty movie clip used. Flash MX 2004 and Flash player 7 users can make use of getNextHighestDepth() for this. Also, when done using each onEnterFrames, the empty movie clip should be removed.

4. Set up a broadcaster of onEnterFrame events
Similar to using empty movie clips but less intrusive, you can use AsBroadcaster to setup the MovieClip object to broadcast onEnterFrame events just like the Key object broadcasts onKeyDown events. This will let you provide onEnterFrame events to non-movie clip objects as though they were movie clips. For this, you only need one movie clip to utilize as a source for enterFrame events instead of many as seen when used empty movie clips for each function needing an onEnterFrame. When AsBroadcaster is setup with the MovieClip object can be used to accept listeners that will then receive onEnterFrame events every frame.

AsBroadcaster.initialize(MovieClip);

_root.createEmptyMovieClip("onEnterFrame_bc",10000)

_root.onEnterFrame_bc.onEnterFrame = function(){

	MovieClip.broadcastMessage("onEnterFrame");

};



myMovieClip.moveRight = function(){

	var mover = new Object();

	mover.target = this;

	MovieClip.addListener(mover);

	mover.onEnterFrame = function(){

		this.target._x++;

	}

}

myMovieClip.moveDown = function(){

	var mover = new Object();

	mover.target = this;

	MovieClip.addListener(mover);

	mover.onEnterFrame = function(){

		this.target._y++;

	}

}



myMovieClip.moveRight();

myMovieClip.moveDown();

As with removing empty movie clips from before, when done with an object receiving onEnterFrame events from MovieClip, you would want to use MovieClip.removeListener() to cleanup after yourself so that onEnterFrame events aren't continuously being broadcasted to invalid objects.

Note that Flash MX 2004 comes with a class that does this for you, mx.transitions.OnEnterFrameBeacon.as.

How can I play a movie clip backwards?

The Quick: Use nextFrame() and prevFrame() in an enterFrame event to control playback; nextFrame to play forwards and prevFrame to play backwards.

The Details: Movie clips/timelines in Flash can be played forwards, stopped and be navigated to any one particular frame. There is no internal means of playing a clip backwards, though. That doesn't mean it can't be done. Using the functions in an enterFrame event of your movie clip can instruct that clip to move either to the next forward frame every frame or the previous frame every frame which effectively plays it backwards. For example:

myMovieClip.playback = "backwards";

myMovieClip.onEnterFrame = function(){

	if (playback == "forwards"){

		this.nextFrame();

	}else if (playback == "backwards"){

		this.prevFrame();

	}else{

		this.stop();

	}

}

Using a custom playback variable, myMovieClip can determine how it progresses to the next frame every frame. Should it go to the previous frame? the next frame? or not move at all?

Note that using nextFrame for forward playback will not correctly play stream-synced sounds placed in the timeline. You would instead want to use play() for normal forward playback.

Why'd my text disappear?

The Quick: Embed your font.

The Details: For non-static text, Flash uses your system fonts to display text in textfields, and does so at a basic level. This method of displaying text display prevents much anything useful to be done with the text such as rotating it, masking it, etc. To give Flash the resources it needs to perform these more complicated operations on text, you would need to embed your fonts so that Flash has the font and its (vector) outlines saved within the swf.

This way, Flash can treat the text as though it were any other vector image. Though embedding your fonts can add to the file size of your final swf, it is usually worth it if not necessary.

Note that if your problem involves masking and you are using the timeline in Flash to define your masks, you can avoid the disappearing text problem by using ActionScript (with setMask) instead of the timeline to apply your mask.

Why isn't setInterval working correctly for my object instance/class?

The Quick: You need to use the secondary setInterval syntax, var interval = setInterval(object, "method", time [,arguments]), in order to specify object scope.

The Details: There are two ways to use setInterval. The most common "primary" way of calling setInterval is by using setInterval with a passed function reference and a time interval in milliseconds for it to repeatedly run. The following will call the Message function every second:

function Message(){

	trace("Welcome");

}

var myInterval = setInterval(Message, 1000);

Nothing unexpected there. However, what you might not understand with setInterval is that object scope, or what the function considers this to be, is not retained in the call. So, if the welcome message was changed from "Welcome" to this, the result would be undefined. However, calling message normally will result in tracing movie clip or object in which it was defined.

function Message(){

	trace(this);

}

var myInterval = setInterval(Message, 1000); // traces undefined

Message(); // traces _level0

However, setInterval provides an alternate "secondary" means of executing functions that allows you to retain object scope for your functions. In place of the function parameter, two new alternate parameters are used, object (Object reference) and method (String). This will then call the function or method with the name passed to method for the object passed as object. For the Message example, the object would be the current timeline/scope or this.

function Message(){

	trace(this);

}

var myInterval = setInterval(this, "Message", 1000); // traces _level0

Instead of setInterval just calling an anonymous Message(), it now calls this["message"]() which retains the scope of this (or whatever object you pass). This use of setInterval is necessary to maintain scope of your class when using it in your class definitions. For any properties in a class method to be accessible from a method call from setInterval, that call will need to have it's scope the scope of the class instance. Take this ActionScript 2.0 class for example:

class Counter {

	public var count:Number = 0;

	private var interval:Number;

	

	function Counter(speed:Number){

		interval = setInterval(this, "increaseCount", speed);

	}

		

	public function increaseCount(speed:Number):Number{

		count++;

		return count;

	}

}

If setInterval was just called as setInterval(increaseCount, speed), the count property would not be accessible since count is referenced from the scope of a Counter class instance so count would never increase.

Can I duplicate a movie clip into another timeline?

The Quick: Not with duplicateMovieClip(), no. An alternative is to use attachMovie() instead.

The Details: The MovieClip duplicateMovieClip method creates duplicates of movie clips (as its name implies). These duplicates, however, are placed in, and only in, the same timeline that the original movie clip exists. You are not able to set the timeline the movie clip is copied to nor can you change the timeline of a movie clip once it exists.

A way to mostly work around this limitation is to use the attachMovie method. It will not copy an existing movie clip in the current timeline, but it will let you create a copy of a movie clip symbol as it exists in your library just so long as you specify a linkage identifier for that symbol (either when the symbol was created or through the symbol's options in the library).

targetTimeline.attachMovie("symbolLinkageID", "instanceName", depth, initObject);

When using attachMovie to duplicate, you will want to make sure the attached movie clip retains the properties of the clip you're duplicating. You can put those properties in an initObject and send them to attachMovie so that they can be copied over into the movie clip created.

// duplicate my_mc in timelineA to timelineB

var initObject = new Object();

initObject._x = timelineA.my_mc._x;

initObject._y = timelineA.my_mc._y;

initObject._width = timelineA.my_mc._width;

initObject._height = timelineA.my_mc._height;

// add any other additional properties needed to be copied

timelineB.attachMovie("myMcID", "my_mc2", 1, initObject);