as3-manipulating z-index dynamically - actionscript-3

So I have trouble with the z-index,
all of my objects have z-index of 0, and as new objects are created they come above the ones that need to be in front.
I know about setting z index commands, but if I have 50 objects, I have to write and manually set z-index for each one, witch is kinda lame.
How can I fix this? This is probably simple but Im new to AS3.

If by z-index you mean the z value of a DisplayObject, that doesn't affect the layering of them. Depth ordering is handled by the display list of its parent.
You can make a DisplayObject go all the way to the back by using container.addChildAt(displayObject, 0); or container.setChildIndex(displayObject,0); if it's already added to that parent's display list.
You don't have to change the indexes of all other children of the same parent.
If you want something to be layered right behind another DisplayObject, first find out what the index of that child is:
var i:uint = container.getChildIndex(theOneToHideBehind);
and then set the index of your DisplayObject to that value:
container.setChildIndex(myDisplayObject, i);

Related

Can I add several sprite children with the same index?

I want 2 sprites on the one index position. The sprites have different coordinates (x attributes), so, each of them are visible when the child position is active.
Clarification, the code:
addChildAt( sprite1, 1 );
addChildAt( sprite2, 1 );
Are both of the sprites visible?
The documentation gives you the answer of what will happen with your snippet.
index:int — The index position to which the child is added. If you specify a currently occupied index position, the child object that exists at that position and all higher positions are moved up one position in the child list.
Two objects can't share the same index because it wouldn't make sense. How would you display two overlapping objects at the same index?
No, you can't. But you can add extra sprite between parent and children to easily control visibility or whatever.
Sample:
parentSprite.addChild(extra)
extra.addChildAt( sprite1, 1 );
extra.addChildAt( sprite2, 2 );

AS3 Removing an object from an array?

I used this line of code to remove an element:
tiles.splice(tiles.indexOf(tiles[i]), 1);
Yet afterwards when I'm checking the value, it's still not null, in fact, it still contains the movieclip it had inside of it.
This worked though:
tiles[tr] = null;
The question is, is it still okay to do it like that?
I have movieclips added and removed to this array and I type removeChild(tiles[tr); before removing it from the array.
I just don't want to encounter some terrible performance in the future,
Thanks.
splice cuts out the element from the Array, and all the above elements move one stept down. Which also reflects in the Array's length.
So the element you are finding is the next element.
Just nulling it will do just that. Leave the rest of the Array as is with an empty position.
Also you dont need to call indexOf if i is already the position you need.
tiles.splice(i, 1)
will do.

AS3 Custom Depth Control

I am trying to create a way of controlling movieclip depths, which movieclip is show above another, so that I can set the depth of a movieclip to any number and they will be displayed with higher values above lower values.
I was thinking of creating a MovieClipDepth class that extends MovieClip with the added property depth, and a Container class that extends DisplayObjectContainer which all objects will be placed inside of.
The Container class will override the addChild method to update the child display order when a child is added.
What I need help with is how do I reorder the children according to
their depth value?
As you can read in the comment below your question, there are several methods for this.
But actually, what you asked "set the depth of a movieclip to any number" can't really be done in AS3. If i'm correct, you could do this in AS2, so...
... how was it ...
_root.createEmptyMovieClip("mc", -1000);
or
_root.createEmptyMovieClip("mc1", 1);
_root.createEmptyMovieClip("mc2", 10);
worked, but does not work in AS3. In AS3 depth starts with 0 and you can't force a DisplayObject to sit on a level what is not continous from zero.
So the depths' of 3 movieclips in a container is only possible with these values: 0, 1, 2.
Depth can't be a negative number for example.
Now, if you want to build a custom depth manager, you can do that, but you have to consider these facts.
So to say, you could create virtual depths.
So I guess, you could override the addChildAt method for example. At the moment, if you would give a wrong number: negative, or higher then the number of children, flash would give back the error:
RangeError: Error #2006: The supplied index is out of bounds.
So mc.addChildAt(newchild, -1000) gives an arror.
But with overriding the method, you could make a trick, so you could store the depths in an array. You could store any numbers and then transform that order for the needs of AS3.
Like pairing the depths with the added children, sorting the array by the depths, then manage the children according to the order.
If you have more questions, feel free to ask, hope this gets you closer to the solution.
I suggest you take a look at this tutorial :
A Tour of Depths Management Methods on the website http://www.flashandmath.com/. I presume you not a newbie .
The link is this:
http://www.flashandmath.com/intermediate/depths/index.html

localToGlobal/globalToLocal AS3 confusion

I want to move a display object from one container to another, but have it appear in the same place on screen.
I thought I'd understood this years ago, but the following does not work:
function moveToNewContainer(obj:DisplayObject, newParent:DisplayObjectContainer):void {
var pos:Point = new Point(obj.x, obj.y);
var currentParent:DisplayObjectContainer = obj.parent;
pos = currentParent.localToGlobal(pos);
currentParent.removeChild(obj);
newParent.addChild(obj);
pos = newParent.globalToLocal(pos);
obj.x = pos.x;
obj.y = pos.y;
}
This doesn't position the object in the same place as I would have expected.
Does anyone know what I am doing wrong, please?
Thanks,
James
Using localToGlobal/globalToLocal and setting the x and y properties like you showed calculates the correct position for the object in its new parent, but does not adjust for other aspects of the transformation such as scaling or rotation. In other words, the object's registration point will indeed remain in the same place, but the object may be rotated, scaled, or sheared differently.
The solution to your problem will need to take into account the transform.concatenatedMatrix properties of the old and new parents--you'll need to multiply the object's transformation matrix by one and then by the inverse of the other, or something along those lines. Leave a comment if you need help working out the math.
There is nothing wrong with your code, provided that both containers have no transformations applied. If your clips are scaled, rotated, etc.. you need to handle that in addition to the coordinate space transformations that localToGlobal and globalToLocal do.
You have to check if your containers are actually placed on stage. If your new container isn't added as a child to stage, function globalToLocal fails, just because it doesnt know how to correctly calculate that data.

ActionScript Measuring 3D Depth

i'm having a difficult time understanding how to control the z property of display objects in a 3D space. i know how depth works, but what i don't understand is how i can get the maximum depth, or the number at which the display object just disappears into the background.
i assume depth is based on the stage's width and height, and that is why assigning the same depth of the same display object appars mismatched with different stage sizes.
so how can i appropriately measure depth?
You need to consider the childIndex property. There is no Z-index in actionscript.
To get the depth you could use:
// returns the number of direct display children in stage
stage.numChildren;
// returns the number of direct display children in you object
myObj.numChildren;
To set the child Z-index use
//sets the newIndex of child in stage
stage.setChildIndex(child:DisplayObject, newIndex:int):void;
If newIndex is 0 then child is top visible element.
newIndex must be in [0, numChildren-1] else flash will throw errors
Take care.
As of Flash 10, there is a 'z' property.
Checkout this link for a tutorial:
http://www.kirupa.com/developer/as3/intro_3d_as3_pg1.htm
it's explained here: Perspective in Flash