We are now ready to get back to our "tiny bubbles" applet shown on the front page of this tutorial and repeated below. This applet illustrates the fact that since library movieclip has its own timeline, it can have its own independent script. On this page we will show how to organize the code, and then we will show how the code can easily be placed in a separate "class file" and remain attached to the movieclip symbol that you created on the stage at authoring time. This latter ability is why this tutorial is in the "Bridging the Gap" section of this site!
Creating the BubbleClip movieclip
We will be generating a large number of bubbles with our script, so we will create a movieclip and link it as before so that we can create instances within ActionScript. In this example, we will attach a script to the bubble movieclip to manage its own motion and evenutally its own removal. Instead of simply showing the final result, we will illustrate the development process by breaking it out into steps.
Step 1. (Note that the result of "Step 1" is shown in the file Bubble.fla linked in the Download section at the bottom of this page.) Create a graphic that looks like a bubble using a circle with radial gradient fill. Select your graphic and choose Modify > Convert to Symbol to turn it into a MovieClip called BubbleClip with registration point in the center. In the Properties panel, give your BubbleClip the instance name mcBubble, and add the following script to the Main Timeline:
mcBubble.addEventListener(Event.ENTER_FRAME, moveMe);
function moveMe(evt:Event):void {
mcBubble.y -= mcBubble.width/2;
if (mcBubble.y < -100) {
mcBubble.removeEventListener(Event.ENTER_FRAME, moveMe);
}
}
Note that the bubble moves half its width each time the ENTER_FRAME event is heard, so bubble speed is relative to its size. Also note that the listener is removed when the button has left the screen. This is not as important for a single bubble as it will be for hundreds!
At this time, use Control > Test Movie to see that this application has the desired effect for a single bubble.
Step 2. Now double-click on your BubbleClip movieclip and a new timeline will open up specific to this movieclip. Within this timeline, add the following script:
this.addEventListener(Event.ENTER_FRAME, moveMe);
function moveMe(evt:Event):void {
this.y -= this.width/2;
if (this.y < -100) {
this.removeEventListener(Event.ENTER_FRAME, moveMe);
this.parent.removeChild(this);
}
}
Note that we refer to particular instance of BubbleClip using the keyword "this" instead of by its specific instance name like we did before. Also note that after removing the listener from this BubbleClip we also remove the clip itself from the display list of its parent. This will be significant when we are generating hundreds of instances.
Now click the phrase "Scene 1" at the top of panel showing the stage to return to the main timeline as we did on the previous page of this tutorial.
Step 3. Open the Library panel (Ctrl+L) and right-click on the BubbleClip movieclip. Choose Linkage from the resulting menu, and select Export for ActionScript as we did on the previous page of this tutorial.
Adding the code to generate lots of bubbles
Now we will discuss the simple code (on the Main Timeline!) that will generate bubbles indefinitely and turn them loose to move on their own. Since the bubbles are being removed automatically, this constant generation of instances of BubbleClip will not cause performance problems.
The entire animation is encapsulated as spBoard so that it can be easily positioned, scaled or rotated. spBubbles is the rectangle that will contain the individual bubbles. The fill color of spBubbles is chosen to match the colors used in the original bubble graphic so we get a nice effect.
var spBoard:Sprite = new Sprite();
spBoard.x = 100;
spBoard.y = 25;
addChild(spBoard);
var spBubbles:Sprite = new Sprite();
spBubbles.graphics.lineStyle(0,0x660066);
spBubbles.graphics.beginFill(0x660066);
spBubbles.graphics.drawRect(0,0,100,300);
spBubbles.graphics.endFill();
spBubbles.x = 50;
spBubbles.y = 50;
spBoard.addChild(spBubbles);
We add a mask to spBubbles so that the bubbles do not have to be strictly controlled to stay within the spBubbles rectangle. We make the mask a child of spBubbles so that spBubbles will carry the mask with it correctly positioned.
var spMask:Sprite = new Sprite();
spMask.graphics.lineStyle(0,0x000000);
spMask.graphics.beginFill(0x000000);
spMask.graphics.drawRect(0,0,100,300);
spMask.graphics.endFill();
spMask.x = 0;
spMask.y = 0;
spBubbles.addChild(spMask);
spBubbles.mask = spMask;
We put a thick frame on three sides of the rectangle to suggest the appearance of a beaker. This is placed on spBoard on a higher level than spBubbles so that the masking of spBubbles does not affect the frame.
var spFrame:Sprite = new Sprite();
spFrame.graphics.lineStyle(6,0x000000);
spFrame.graphics.moveTo(0,0);
spFrame.graphics.lineTo(0,300);
spFrame.graphics.lineTo(100,300);
spFrame.graphics.lineTo(100,0);
spFrame.x = spBubbles.x;
spFrame.y = spBubbles.y;
spBoard.addChild(spFrame);
We use a timer to create a new random instance of BubbleClip every 0.1 seconds. We randomly place the bubble and scale it randomly between 25% and 50% of its original size. The updateAfterEvent method makes the motion smoother since the timer events might happen between ENTER_FRAME events.
var tm:Timer = new Timer(100);
tm.addEventListener(TimerEvent.TIMER, newBubble);
function newBubble(tevt:TimerEvent):void {
var thisBubble:BubbleClip = new BubbleClip();
thisBubble.x = 100*Math.random();
thisBubble.y = 400 + 60*Math.random();
var r:Number = 0.25*(1+Math.random());
thisBubble.scaleX = r;
thisBubble.scaleY = r;
spBubbles.addChild(thisBubble);
tevt.updateAfterEvent();
}
// Start the timer to start "bubble production."
tm.start();
Download
- The source file containing only the result of "Step 1" is Bubble.fla
- The source file containing the results of all steps is FreeBubbles.fla










