DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 13.1 Creating an Object to Control Sound

13.1.1 Problem

You want to control sounds at runtime.

13.1.2 Solution

Create a new movie clip to serve as the sound's target and then pass a reference to that clip to the Sound( ) constructor function (to create a new Sound object). Alternatively, create and invoke a custom createNewSound( ) method that handles this process automatically.

13.1.3 Discussion

Sound objects enable you to load sounds, play sounds, and control the volume and panning of sounds within your Flash movies. A Sound object must target a movie clip (_root is also a valid target). The audio that is controlled must be placed in the movie clip's timeline at authoring time or loaded into the movie clip at runtime using attachSound( ) or loadSound( ). In any case, it is possible for you to place/load multiple sounds into a single movie clip, but doing so is discouraged. The reason for this is that a Sound object controls the audio in the target movie clip as a whole, so it is not possible to control each of the sounds separately if they are all in the same movie clip. Therefore, it is better to place/load each sound into its own movie clip and create a separate Sound object to control each one.

When you create a new Sound object, specify a target movie clip. To control sounds in the current timeline, specify the keyword this as the target.

// Incorrect. This does not work properly.
mySound0_sound = new Sound(  );  
// Correct. This targets the current timeline.
mySound1_sound = new Sound(this);
// Correct. This targets mySoundHolder_mc.
mySound2_sound = new Sound(mySoundHolder_mc);

When you are using attachSound( ) or loadSound( ) to add audio to a movie clip, it is a good idea to use the createEmptyMovieClip( ) method to create the clip:

// Create a new movie clip to hold the audio. Then create a new Sound object and pass
// it a reference to the holder movie clip.
_root.createEmptyMovieClip("soundHolder0_mc", 1);
mySound0_sound = new Sound(soundHolder0_mc);

// To manage additional sounds, use the same process to create holder movie clips and
// Sound objects for each one.
_root.createEmptyMovieClip("soundHolder1_mc", 2);
mySound1_sound = new Sound(soundHolder1_mc);

As you can see, the preceding process is repetitive when creating multiple sounds in your movie. You have to create each holder movie clip and Sound object and keep track of numbers and depths. You can automate this process with a custom createNewSound( ) method. The createNewSound( ) method should be defined as a static method for the Sound class. (A static method is a method that is called directly from the class, rather than from an object instance of the class.)

The custom createNewSound( ) method returns a new Sound object, which targets an automatically generated holder movie clip. The movie clip is created within _root by default, but you can specify a parent movie clip as an optional parameter. Add the following createNewSound( ) method definition to an external Sound.as file for easy inclusion in other projects:

// This code requires getNewDepth(  ) from Chapter 7, so include MovieClip.as.
#include "MovieClip.as"

Sound.createNewSound = function (parentClip) {

  // If parentClip is specified, create the sound holder movie clip in that timeline.
  // Otherwise, use _root as the parent clip.
  if (parentClip == undefined) {
    parentClip = _root;
  }

  // soundCount keeps track of the holder movie clips that are created. 
  // It defaults to 0.
  if (parentClip.soundCount == undefined) {
    parentClip.soundCount = 0;
  }

  // Create a holder movie clip in parentClip using createEmptyMovieClip(  ). Give it a
  // unique name by appending the value of soundCount to "soundHolderClip". Give each
  // clip a unique depth using getNewDepth(  ).
  var soundHolder_mc = parentClip.createEmptyMovieClip("soundHolderClip" + 
                                                 parentClip.soundCount + "_mc", 
                                                 parentClip.getNewDepth(  ));

  // Create the Sound object that targets the holder movie clip.
  var soundObj_sound = new Sound(soundHolder_mc);

  // Store a reference to the clip in the Sound 
  // object's mc property for later access.
  soundObj_sound.mc = soundHolder_mc;

  // Use soundHolder_mc.parent to establish a relationship between the sound 
  // holder movie clip and the Sound object. Use soundObj_sound.parent to establish 
  // a relationship between the Sound object and the parent clip. These 
  // relationships are important so that each object has a reference to one 
  // another, which they would not otherwise have. This enables communication 
  // between the objects for the purposes of creating fades (see Recipe 13.14 
  // and Recipe 13.15) and other functionality.
  soundHolder_mc.parent = soundObj_sound;
  soundObj_sound.parent = parentClip;

  // Increment soundCount so that the next holder movie clip has a unique name.
  parentClip.soundCount++;

  // If an allSounds array doesn't already exist, create it. It contains references
  // to all the sounds that have been created using createNewSound(  ). This is useful
  // when you want to perform an action on all the sounds.
  if (_global.allSounds == undefined) {
    _global.allSounds = new Array(  );
  }

  // Add the new sound to the array.
  _global.allSounds.push(soundObj_sound);

  // Return the Sound object.
  return soundObj_sound;
};

Here is an example of how to use the createNewSound( ) method:

#include "Sound.as"

// Create a new Sound object named mySound_sound by calling the static method
// Sound.createNewSound(  ). You do not need to create a holder movie clip because the
// method does it for you.
mySound_sound = Sound.createNewSound(  );

// You can access the target holder movie clip via the Sound object's mc property.
// Assuming that mySound_sound was the first Sound object created in a movie, this
// trace(  ) statement displays: _level0.soundHolderClip0
trace(mySound_sound.mc);

13.1.4 See Also

This recipe explained how to create a Sound object to control sounds, but not how to play a sound. Refer to subsequent recipes for details on using a Sound object's full capabilities. For details on attaching sounds at runtime using attachSound( ), see Recipe 13.2. For tips on using loadSound( ), see Recipe 15.5. See Recipe 2.7 to determine whether the device is capable of playing sounds.

    [ Team LiB ] Previous Section Next Section