Internet / Software Applications

Macromedia Flash MX 2004 ActionScript Programming Tutorial

Attaching Movie Clips

We’d like to add a small crash-like explosion of fire when the asteroid hits the ship. We could do this in several ways, but this is a good place to demonstrate the attachMovie method.

You’ve already learned how to duplicate movie clips using the duplicateMovieClip method of the MovieClip object. The attachMovie method does the same thing, but it creates a movie clip from the library, rather than from the stage. Using attachMovie, we don’t need to already have an instance of the movie clip on the stage to make a duplicate.

For our explosion, we again grabbed a piece of clip art and created a simple motion tween in a movie clip called “explosion_clip”. The animation makes the explosion grow in size. When we created the movie clip, Flash automatically placed it in the library:

It doesn’t appear anywhere on the stage.

To use the attachMovie method, we need to give the explosion movie clip a unique identifier, called a linkage ID. This is like an instance name, which lets us refer to the movie clip in code. After we give it a linkage ID, we’ll add code to our asteroid_mc movie clip to attach the explosion movie clip when the asteroid collides with the ship:

  1. Right-click the explosion movie clip in the library and select Linkage from the shortcut menu.
  2. In the Linkage Properties dialog, select the Export for ActionScript checkbox. This enables the Identifier field.
  3. In the Identifier field, enter a unique identifier for the clip. We’re using “explosion”:

  1. Click OK.
  2. On the stage, select the asteroid_mc movie clip instance and add the following code to the if statement before the gotoAndPlay action:

this.attachMovie(“explosion”, “explosion_mc”, _root.num_clips);

The code should now look like the following:

Again, “this” refers to the asteroid_mc movie clip—the movie clip we’re attaching our new explosion movie clip to. The attachMovie method has 3 arguments. The first is the linkage ID of the movie clip being attached from the library. The second is the name we want to give to the instance of the attached movie clip; we’re calling it “explosion_mc”. The third is the target level. We’re again using our num_clips variable for this, targeting its location on the main timeline using _root.num_clips.

  1. Save and test the movie. The fiery explosion should appear when the asteroid collides with the ship, and the ship shatters.

Using the onMovieClip(EnterFrame) Event Handler for Repetitive Stage Updates

We’ve now built a small Asteroids-type game that detects the collision of a randomly-positioned asteroid with a space ship. When the asteroid collides with the ship, the ship explodes and the game ends. It isn’t much a game, though, since the user can’t interact with it to prevent the asteroids from crashing into the ship. In this section, we’ll add laser fire to our movie, using the onMovieClip(EnterFrame) event handler to update the movement of the laser beam as it travels across the stage.

We’ve created two new movie clips: one is the “laser” movie clip, which contains our laser graphic, and the other is a clip called “laser_clip”, which simply contains our “laser” movie clip. The “laser_clip” movie clip functions as an outer container movie clip, which will allow us to attach code to the “laser” movie clip to direct its movement. This code will be duplicated each time a laser is created at run-time. We had to do this, since the laser isn’t on the stage at design time, as the asteroid_clip was. Below, you can see the “laser” clip selected inside the “laser_clip” clip:

We know lasers aren’t really round, but this was fast and easy; it’s just a small circle with a gradient fill. You can create any shape and color laser you’d like, or grab some more clip art for it.

We’re going to attach code here to animate the laser when it’s fired, so there’s no need to animate the graphic. You learned earlier that loop statements don’t effectively update the stage during execution—only at the end of the loop’s execution do you see the results. So if we want to show our laser moving across the stage at increments, a loop isn’t the best way to do that. Instead, we’re going to use the onClipEvent(enterFrame) event handler.

The enterFrame event executes code each time an object enters a frame. What this means for us is that as long as the laser_clip exists in the movie, it will continue to execute code contained in the laser movie clip’s onClipEvent(enterFrame) handler, at the frame rate you specified for the document. It forms its own loop, which makes creating a loop unnecessary. We’re going to move the laser each time it enters a frame by changing its y-coordinate position by -10 pixels (an upward movement). With the laser movie clip selected inside the laser_clip movie clip, type the following into the Actions panel:

onClipEvent(enterFrame) {

_y -= 10;

}

The _y property changes the vertical position of the movie clip by repositioning the clip along the y axis. The upper left-hand corner of the stage is at coordinates (0,0), with the first coordinate representing the x axis and the second coordinate representing the y axis. As you move to the right and down, the numbers increase; as you move to the left and up, the numbers increase. We used the -= operator to decrement the _y property by 10. This moves the laser up the stage by 10 pixels each time the clip enters a frame.

Next, we need to think about how we’re going to test its collision with an asteroid. Presumably, the user will fire a number of lasers with several asteroids on screen. For each laser, we’re going to need to test whether or not it hits a given asteroid. We can place the hit test in the laser_clip, since it will be duplicated every time the user fires (the same as we did with the asteroid to test each asteroid’s collision with the ship), but we’re also going to have a number of dynamically-created asteroids on the screen at the same time. The easiest way to test for a collision with each of these is to place the asteroids into an array:

  1. Return to Frame 1 of the main timeline and create a new array near the top of the code, where you’ve declared your variables. Specify a length of 10 and assign the original asteroid_mc movie clip to the first index position:

var asteroidArray = new Array(10);

asteroidArray[0] = _root.asteroid_mc;

  1. Scroll down to the makeAsteroid() function and add the following code beneath the lines that position the duplicate movie clip:

//add to array

asteroidArray[num_clips] = _root[“asteroid_mc” + num_clips];

This adds each duplicate created to the array.

  1. Next, we’re going to doctor our asteroid_clip movie clip to add an explosion. This is simpler than attaching and removing an explosion movie clip for each hit. Open up the asteroid_clip in Edit mode and add about 5 frames to the end of the asteroid layer. Make the first a keyframe. Drag the explosion movie clip from the library onto the first of the new frames and delete the asteroid graphic. Place a stop action at the end of the new frames.

Note:

We’ve also been tweaking the length of the animation and the positions of the initial asteroid and duplicate asteroids so the ship doesn’t blow up too soon or too late. You can continue to test and tweak as you go along.

  1. Now, return to the laser_clip movie clip, enter Edit mode, and select the laser movie clip. Add the following hit test to the onClipEvent(enterFrame) event handler:

for(var i = 0; i < _root.asteroidArray.length; i++) {

if (this.hitTest(_root.asteroidArray[i])) {

_root.asteroidArray[i].gotoAndPlay(37);

_parent.removeMovieClip();

}

}

All the code in the movie clip should now look like this:

onClipEvent(enterFrame) {

_y -= 10;

for(var i = 0; i < _root.asteroidArray.length; i++) {

if (this.hitTest(_root.asteroidArray[i])) {

_root.asteroidArray[i].gotoAndPlay(37);

_parent.removeMovieClip();

}

}

}

The for statement loops through each of the asteroids in the array and tests whether it’s hit the current laser. If it has, the asteroid moves to Frame 37 of its timeline to play the explosion. Then the laser_clip movie clip (_parent) is removed. This loop is executed every time the laser movie clip enters a new frame (and a new position on the stage).

We haven’t yet given the user a means to fire the laser, though. We’re going to do that right after we add some sound effects.