DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 7.16 Changing Stacking Order

7.16.1 Problem

You want to swap the depths of two movie clips.

7.16.2 Solution

Use the swapDepths( ) method.

7.16.3 Discussion

The swapDepths( ) method swaps the depths of any two movie clips. You should call it from one of the two movie clips and pass it a reference to the other:

myMovieClip1.swapDepths(myMovieClip2);

One way in which this method is particularly useful is in swapping the depths of two movie clips when hitTest( ) detects that one overlaps the other. The following example uses this concept but also illustrates the problem that can occur when trying to use this technique.

The following example shows a white circle and a black circle that overlap and rapidly change depths. The result is a very fast blinking effect, which may be induce seizures in readers prone to epilepsy or may induce nausea in sensitive viewers. Please exercise caution.

The following code swaps two clips' depths when they overlap:

// Include DrawingMethods.as from Chapter 4 for its drawCircle(  ) method.
#include "DrawingMethods.as"

// Draw two circle movie clips: one black and one white.
_root.createEmptyMovieClip("circle1", 1);
circle1.lineStyle(1, 0x000000, 100);
circle1.beginFill(0xFFFFFF, 100);
circle1.drawCircle(100);
circle1.endFill(  );

_root.createEmptyMovieClip("circle2", 2);
circle2.lineStyle(1, 0x000000, 100);
circle2.beginFill(0, 100);
circle2.drawCircle(100);
circle2.endFill(  );

// Set each movie clip to be on the visible part of the Stage.
circle1._x = circle2._x = 200;
circle1._y = circle2._y = 200;

// Make each movie clip draggable when clicked.
circle1.onPress = function (  ) {
  this.startDrag(  );
};

circle1.onRelease = function (  ) {
  this.stopDrag(  );
};

circle2.onPress = function (  ) {
  this.startDrag(  );
};

circle2.onRelease = function (  ) {
  this.stopDrag(  );
};

// Continually check to see if circle1 and circle2 overlap. If so, call the 
// swapDepths(  ) method to switch their depths.
_root.onEnterFrame = function (  ) {
  if (circle1.hitTest(circle2)) {
    circle1.swapDepths(circle2);
  }
};

As you can see, the depths swap back and forth over and over. You need to add more logic to the code to instruct the movie how to perform a more intelligent swap. The basic process is that the onEnterFrame( ) method needs to know which movie clip should remain on top, and it should perform that swap only if the movie clip is not already on top. Here is how you can rewrite the previous code to fix the problem (changes are shown in bold).

 . . . 
circle1.onPress = function (  ) {
  this.startDrag(  );
 
  // Set a dragged property in _root, so _root knows that
  //  circle1 is being dragged. And set a nondragged property in _root,
  // so _root knows that circle2 is not being dragged.
  _root.dragged = this;
  _root.nondragged = _root.circle2;
};

circle1.onRelease = function (  ) {
  this.stopDrag(  );
};

circle2.onPress = function (  ) {
  this.startDrag(  );

  // Set the dragged and nondragged properties as before, but with the values
  // reversed from when circle1 was being dragged.
  _root.dragged = this;
  _root.nondragged = _root.circle1;
};

circle2.onRelease = function (  ) {
  this.stopDrag(  );
};

_root.onEnterFrame = function (  ) {

  // Now check to see if the two movie clips are overlapping and see if the dragged
  // movie clip is below the nondragged movie 


clip. If so, swap them.
  if (this.dragged.hitTest(this.nondragged) &&
      this.dragged.getDepth() < this.nondragged.getDepth(  )) {
    this.dragged.swapDepths(this.nondragged);
  }
};

7.16.4 See Also

Recipe 7.11

    [ Team LiB ] Previous Section Next Section