3
votes

I have a simple function that, when you click on a button, adds a movie clip to the stage in a random x and y position.

The issue I am having is that the new movie clips eventually cover up the button. I tried to change the z-index of the newly created movie clip to be below the z-index of the button, but that doesn't solve the problem.

How does one stop the new movie clips from covering up an element that already exists?

friends1_btn.addEventListener(MouseEvent.CLICK, friendMaker);

function friendMaker(evt:MouseEvent):void {
    var newFriend:Teddy = new Teddy();
    newFriend.x = Math.random()*stage.width;
    newFriend.y = Math.random()*stage.height;
    newFriend.z = 0;
    stage.addChild(newFriend);
}
6

6 Answers

12
votes

Or alternatively - and maybe more use longterm - don't have all the added objects as children of the same layer as the button.

So instead of:

stage
  |
  +--- object 1
  |
  +--- object 2
  |
  +--- button
  |
  +--- object 3

Have:

stage
  |
  +--- object layer
  |       |
  |       +--- object 1
  |       |
  |       +--- object 2
  |
  +--- button

Or even:

stage
  |
  +--- object layer
  |       |
  |       +--- object 1
  |       |
  |       +--- object 2
  |
  +--- button layer
          |
          +--- button

Where object layer and button layer could simply be Sprite objects, i.e.:

var objectLayer:Sprite=new Sprite();
var buttonLayer:Sprite=new Sprite();
stage.addChild(objectLayer);
stage.addChild(buttonLayer);
buttonLayer.addChild(myButton);

and so on.

I think you'll find it's more useful to get into that way of thinking longterm rather than just to shift the z-indices around.

Incidentally, the updated Flash Player 10 does have a .z property (even though it's not in the documentation) - as Reuben says, it's used for the new 3D transforms. Sadly 3D transforms have no support whatsoever for z-sorting or z layering, so don't help in this case.

2
votes

I know this question has already been answered, but you could also use addChildAt() to specify which index you want to add the DisplayObject at, you can use numChildren, or keep your own record of indexes at which to add.

private var friends1_btn:Sprite;

function friendMaker(evt:MouseEvent):void
{
    var newFriend:Teddy = new Teddy();
    newFriend.x = Math.random()*stage.width;
    newFriend.y = Math.random()*stage.height;
    stage.addChildAt(newFriend, stage.numChildren-1);
    //or if your not sure if the button will always be on top
    stage.addChildAt(newFriend, stage.getChildIndex(friends1_btn)-1);
}

You do NOT want to keep adding the original button to the stage as this will keep triggering the event Event.ADDED_TO_STAGE, it will also cause flickering as the button will be removed from the stage briefly due to the way the display list works.

0
votes

MovieClip doesn't have a propery named 'z' in AS3 (reference)

You should read up on the new display list model for AS3. It should help you understand how objects can be layered on top of one another.

0
votes

swapChildren() should do it.

friends1_btn.addEventListener(MouseEvent.CLICK, friendMaker);

function friendMaker(evt:MouseEvent):void {
    var newFriend:Teddy = new Teddy();
    newFriend.x = Math.random()*stage.width;
    newFriend.y = Math.random()*stage.height;
    stage.addChild(newFriend);
    stage.swapChildren(newFriend, friends1_btn);
}
0
votes

This way will ensure the button is the very top item no matter what you do. Calling addChild on something that is already added (in the same container) will readd it to the top.

friends1_btn.addEventListener(MouseEvent.CLICK, friendMaker);

    function friendMaker(evt:MouseEvent):void {
        var newFriend:Teddy = new Teddy();
        newFriend.x = Math.random()*stage.width;
        newFriend.y = Math.random()*stage.height;

        stage.addChild(newFriend);
        stage.addChild(friends1_btn);
    }

You can also do the same by replacing

stage.addChild(friends1_btn);

with

stage.swapChildrenAt(stage.getChildIndex(friends1_btn), stage.numChildren - 1);
0
votes

The "z" property of a MovieClip is used for 3D transformations in Flash Player 10 - instead you need to set the child index of the MovieClip explicitly

A good way is to manually set the index of friends1_btn to the front:

friends1_btn.addEventListener(MouseEvent.CLICK, friendMaker);

function friendMaker(evt:MouseEvent):void {
    var newFriend:Teddy = new Teddy();
    newFriend.x = Math.random()*stage.width;
    newFriend.y = Math.random()*stage.height;
    stage.addChild(newFriend);
    stage.setChildIndex(friends1_btn,stage.numChildren-1);
}

(A side note - if you want to randomly position a MovieClip on the Stage, you should use stage.stageWidth and stage.stageHeight, otherwise you are only getting the width and height of objects on the stage, not the stage itself).