AS Reference  :  Notes Index  :  Resources  :  About/Contact  :  Downloads

Adding Movieclips to a Movie While It's Running

There are three ways to create new movieclips on stage while a movie is running:

  1. You can create a new movieclip from scratch, using createEmptyMovieClip (a method of the MovieClip class), and use the drawing API to give it content or load external content (pictures, video, sound) into it
  2. You can use attachMovie to add a movieclip which has been stored in the movie's library and given a linkage id.
  3. You can use duplicateMovie to create copies of a movieclip already on stage, as described on the distorting magnifier page.

attachMovie

The attachMovie method (built in to all movieclips) allows any movieclip in the library which has been given a linkage id to be attached to an existing movieclip (or the main timeline) in the movie while it is running. The format for doing so is:

where the last line is gray to show that it is optional. When you attach a movieclip from the library, you must specify what you are attaching it to, what is its name (linkageId) in the library, what will be its instance name, and what depth (0 to some ridiculously big number that I don't remember) it will be within the timeline it is being attached to. Note that if you attach a movieclip at the same depth as something that already exists in the timeline at that depth, the previous thing will be deleted.

Specifying initial conditions for the item being attached

If you want to specify anything in particular about the movieclip being attached, like its position (within the timeline it is being attached to), its xscale or height or width, or a property that you assign and will use later, the place to do that is in the last parameter of the attachMovie.

To attach a one-frame snowflake movieclip to the stage at 100, 100, for example, you would first create a snowflake movieclip with symbol name flake, delete it from the stage (it's still in the library), open the library and right-click on the snowflake movieclip, check Export For Actionscript, and make sure "flake" (without the quotes) appears in the Identifier box. If you want to use an identifier other than the symbol's name, you can type in a new one. Then in frame 1 of the main movie, put this code:

this.attachMovie("flake", "f", 0, {_x:100, _y:100});

That will cause the flake movieclip to be attached to the main timeline ("this", because your code is on the main timeline) at depth 0 (ie, physically behind anything that might be added later at a higher depth) and named f. It will be positioned at 100, 100 as soon as it appears.

Keeping a reference to the attached movieclip

If you look in the Help documents, you'll see that attachMovie returns a value of type MovieClip -- that is, it returns a reference to the movieclip that has just been attached. This can be useful if you want to do anything further to the clip after attaching it, like assigning an event handler to it. This code in frame 1 will allow you to create a variable to hold that pointer and assign a value to it:

var flake:MovieClip;
flake = this.attachMovie("flake", "f", 0, {_x:100, _y:100});

You can now refer to the clip you added in a number of ways -- either by its instance name (this.f or this["f"]) or by the reference you created (flake). Say you now want this flake to float down the screen until it reaches the bottom (of a 300-pixel high screen) and then delete itself. You can create a fallAndDelete function and use the reference you created to assign an event handler to the flake:

var flake:MovieClip;

function fallAndDelete() {
   this._y += 2;
   // assume flake has center registration point
   if (this._y > 300 + this._height/2) {
      this.removeMovieClip();
   }
}

flake = this.attachMovie("flake", "f", 0, {_x:100, _y:100});
flake.onEnterFrame = fallAndDelete;

Assigning your own properties to the movieclip

The example above sends the flake drifting downward at 2 pixels per frame. If you want to tell each movieclip its own speed, you can assign a property to the clip when it is attached so it will know its own speed:

var flake:MovieClip;

function fallAndDelete() {
   this._y += this.speed;
   if (this._y > 300 + this._height/2) {
      this.removeMovieClip();
   }
}

flake = this.attachMovie("flake", "f", 0, {_x:100, _y:100, speed:2});
flake.onEnterFrame = fallAndDelete;

Let's add a rotation property also, and change the example to attach three copies of flake to the stage at even intervals, causing them all to drift downward and spin a bit as they go:

var flake:MovieClip;

function fallAndDelete() {
   this._y += this.speed;
   this._rotation += this.rdegrees;
   if (this._y > 300 + this._height/2) {
      this.removeMovieClip();
   }
}

for (var i=0; i < 3; i++) {
   flake = this.attachMovie("flake", "f"+i, i, {
      _x:100+i*100, 
      _y:100, 
      speed:2, 
      rdegrees:2
      });
   flake.onEnterFrame = fallAndDelete;
}

Notice the places where strings and number values were replaced with expressions involving i, which is incremented from 0 to 1 to 2 as each clip is added. That code produced a line of three movieclips all drifting down and turning at exactly the same rate: a perfect little snowflake drill team.

Adding Randomness

It would probably be nicer to have each flake added with some randomness about it, so here is an example of making a little 100-flake snowstorm instead, where the size, position, rotation and transparency of each snowflake is a little different from its neighbor. Notice that also, instead of deleting each movieclip as it hits the bottom of the stage, we have it move itself back up to the top of the stage, somewhere between 0 and 3 pixels above the top of the stage (and renamed the function accordingly):

var flake:MovieClip;

// returns a real number between a and b
function randomBetween(a:Number, b:Number):Number {
   return a + Math.random()*(b-a+1);
}

function fallAndRestart() {
   this._y += this.speed;
   this._rotation += this.rdegrees;
   if (this._y > 300 + this._height/2) {
      // don't delete it; start it again above the stage
      this._y = randomBetween(0-this._height/2, 3-this._height/2);
   }
}

for (var i=0; i < 100; i++) {
   flake = this.attachMovie("flake", "f"+i, i, {
      _x:randomBetween(0, 400), 
      _y:randomBetween(0, 300),
      _alpha:randomBetween(50, 100),
      speed:randomBetween(1, 3),
      rdegrees:randomBetween(1, 4)
      });
   flake.onEnterFrame = fallAndRestart;
}

But there's still something not right about that snowstorm. To make it more realistic (a bit anyway), the snowflakes in the foreground should be bigger, brighter and slower moving than those in the background. We'll make an array called ranges with 3 elements, each of which describes the range of values to apply for a foreground flake, an intermediate flake, and a background flake. Every time a flake is created, a random element of ranges will be selected to define which type of new snowflake is to be created, and to specify the range of values from which a random number will be selected for each of its attributes. Here is that code:

var flake:MovieClip;
var ranges:Array = [

   // big foreground flakes
    {size1:80, size2:100, alpha1:95, alpha2:100, speed1:1, speed2:2},
	
   // medium flakes
    {size1:70, size2:80, alpha1:80, alpha2:95, speed1:2, speed2:3},
	
   // small background flakes
    {size1:40, size2:70, alpha1:60, alpha2:80, speed1:3, speed2:4}
	
	];

function randomBetween(a:Number, b:Number):Number {
   return a + Math.random()*(b-a+1);
}

function fallAndRestart() {
   this._y += this.speed;
   this._rotation += this.rdegrees;
   if (this._y > 300 + this._height/2) {
      this._y = randomBetween(0-this._height/2, 3-this._height/2);
   }
}

for (var i=0; i < 100; i++) {
   // pick a random element of ranges
   var r:Number = randomBetween(0, 2);
   
   // find a scale to apply horizontally and vertically
   var newscale:Number = randomBetween(ranges[r].size1, ranges[r].size2);
   
   // find and apply all properties, using ranges array
   flake = this.attachMovie("flake", "f"+i, i, {
      _x:randomBetween(0, 400), 
      _y:randomBetween(0, 300),
      _xscale:newscale,
      _yscale:newscale,
      _alpha:randomBetween(ranges[r].alpha1, ranges[r].alpha2),
      speed:randomBetween(ranges[r].speed1, ranges[r].speed2),
      rdegrees:randomBetween(ranges[r].speed1, ranges[r].speed2)
      });
   flake.onEnterFrame = fallAndRestart;
}

As a final embellishment, you can change the x position of the flakes in FallAndRestart so that they drift in the direction of the mouse, as in the example at the top of this page. That code is in the fla available by subscription in the link at right. In the final movie, I used a frame rate of 15 fps, and small ranges like 0.5 - 0.7 for the speed property to make the snowflakes drift.

Intro
Flash: What & How
Example Sites
Create
Draw, Edit Shapes
Gradients
More Drawing Tips
Import
A Sample
Animate
Frames, Keyframes
Motion Tweens
More Motion Tweens
Shape Tweens
Masks
Control
Stop/Replay
Movieclips Intro
Movieclip Reference
Site Structure 1
Slideshow Movieclip
Contact Form
Scroll Resume
Preloader
Site Structure 2
Publish
Display Options
Player Detection
Optimize
AS 2.0 Basics
Intro to Syntax
Playhead Commands
Playhead Cmds 2
Coded Tween
onEnterFrame
Intro to Classes
Declare/Assign
Comments, Trace
Simple Data Types
Arrays & Objects
Code Blocks
Operators
Beyond Buttons
Code Structure
Toggle Controls
Group of Buttons
Drag and Hit
Distort Magnifier
Scroll Text
Bee Game
Dart Shooter
Sound Control
Easing Slider
Easing Slider 2
Components Intro
Timers & Delays
Dynamic Content
Intro
Drawing API
Create Text
Attach Movieclips
Easing Slider 3
Easing Slider 4
Load jpg/swf
Sliding Viewer
Preload swf
XML
Easing Slider 5
Server Comm
LoadVars (w/ PHP)
AS - PHP Lookup
Text File
Database 1:LoadVars
Database 2:Remoting
Read from directory
AS 2.0 Classes
Intro
Math
Key
Date
Color
EventDispatcher
New Samples
Pie Chart
Event-model Emailer
Tween Sequence
Fuse Sequence
SVG in Flash
Bitmap Topo
SWF as Data Holder
Two-level Menu
Yahoo! Flash Maps
Class-based Game
ASTB Samples
Disclaimer
3D Outlines
Bounce Collide
Address Book
Save Drawings
Home  :  Notes Index  :  Resources  :  About/Contact  :  Downloads