-
Senior Member
Depth Swapping in as3
Im trying to implement some depth swapping in my engine, what I want is characters to change depths depending their Y coordinate, is 2d so it has that 3d depth feeling (like those old beat em ups konami used to make, the simpsons, tmnt remember?) in order to do that I need to swap character depths on the fly.
So far what Im doing is creating different child instances of a movieClip in the stage (back, medium, close) and I addchild the movieClip to its depth.
pseudocode
Code:
back=new Sprite();
addChild(back)
back.addChild(backgroundSprite)
medium.addChild(characterSprite)
etc...
But I dont know how to change the characters depth.
-
Senior Member
So u got 3 clips on stage and you want to switch char sprite between those 3?
-
in as3 there is not really a "depth" any more...it's now index...so you are gonna have to use swapChildren(mc1, mc2) or swapChildrenAt(mc1_index, mc2_index)- this of course means a bit more code scripted...
var child1= this.getChildByName("mc1")
var child2=this.getChildByName("mc2")
var index_1=this.getChildIndex(child1);
var index_2=this.getChildIndex(child2);
this.swapChildren(index_1,index_2)
-
this method will stack your DisplayObjects properly- it returns a Boolean indicating whether a swap was made in case you need to handle this (graphically or otherwise):
Code:
public static function sortChildrenByFauxZ( container:DisplayObjectContainer ) : Boolean
{
var numChildren:int = container.numChildren;
//no need to sort (zero or one child)
if( numChildren < 2 ) return false;
var depthsSwapped:Boolean;
//create an Array to sort children
var children:Array = new Array( numChildren );
var i:int = -1;
while( ++i < numChildren )
{
children[ i ] = container.getChildAt( i );
}
//sort by children's y position
children.sortOn( "y", Array.NUMERIC );
var child:DisplayObject;
i = -1;
while( ++i < numChildren )
{
child = DisplayObject( children[ i ] );
//only set new depth if necessary
if( i != container.getChildIndex( child ) )
{
depthsSwapped = true;
//set their new position
container.setChildIndex( child, i );
}
}
//returns true if 1 or more swaps were made, false otherwise
return depthsSwapped;
}
-
Senior Member
Thanks new black thats exactly what I needed
-
np- i realized that due to the internal means depths get reassigned, you don't need to iterate over all of the children when setting their respective indices... the last DisplayObject will always occupy the last index. I can't edit my post, but it's as simple as changing the second "while( ++i < numChildren )" to "while( ++i < numChildren - 1 )"
-
This should be faster.
Code:
function sortZ (dParent:DisplayObjectContainer):void {
for (var i:int = dParent.numChildren - 1; i > 0; i--) {
var bFlipped:Boolean = false;
for (var o:int = 0; o < i; o++) {
if (dParent.getChildAt(o).y > dParent.getChildAt(o+1).y) {
dParent.swapChildrenAt(o,o+1);
bFlipped = true;
}
}
if (!bFlipped)
return;
}
}
It does a bubble sort on the passed DisplayObjectContainer. The advantage here is that I don't allocate extra memory for an array, and only perform one sort. I choose a bubble sort since its easy to implement and its probable that the elements will already be in order.
On my computer, sortZ() performs 5000 iterations in 119ms, and sortChildrenByFauxZ() takes 421ms for the same. The test was done on 80 display objects that were not reshuffled between sorts, I think that represents the most common use case well.
Last edited by 691175002; 02-18-2008 at 04:15 PM.
The greatest pleasure in life is doing what people say you cannot do.
- Walter Bagehot
The height of cleverness is to be able to conceal it.
- Francois de La Rochefoucauld
-
that better be faster!
i addressed the problem from an illustrative (instead of performance-minded) perspective... which i should think twice about doing in the games forum!
anyway, nicely written algorithm
-
Would this be less fast?
try
{
_conatiner.setChildIndex(this, this.y);
}
catch ( e:RangeError )
{
trace("It's ok - I know this will be out of bounds - run it anyway");
}
use setChildIndex and catch then ignore the range error - seems like it would be faster to me than looping twice - PLease let me know if incorrect
Last edited by kevineleven; 04-16-2008 at 11:49 AM.
-
Senior Member
http://www.errorware.co.uk/clients/itkwando/demo01/
that's my version of said effect just in case anyone is at all interested
Chris error x
-
Originally Posted by 691175002
On my computer, sortZ() performs 5000 iterations in 119ms, and sortChildrenByFauxZ() takes 421ms for the same.
Very cool function, what do you mean by iterations though? Does 1 iteration = 1 call to the function you wrote sorting 80 display objects?
-
so how would you implement this into a game? I mean if i just copy and paste that into a frame on the main stage it's not going to work is it?
I'm having problems trying to create this type of function for a side scrolling beat em up im working on. I need a function i can use to change depth on the fly as an enemy is higher or lower than me to make it look 3dish
I'd really like to know how to use this...
EDIT:
Well after trying all day to work it out it turns out i found a pretty easy way to do it 20 seconds after posting this...
Code:
var stuff:Array = [player, enemy01, enemy02];
addEventListener(Event.ENTER_FRAME, swap);
function swap(e:Event):void
{
for (var i = 0; i < stuff.length - 1; i++)
for (var j = i + 1; j < stuff.length; j++)
{
var a = stuff [i], b = stuff [j];
if ((a.y > b.y) != (getChildIndex (a) > getChildIndex (b)))
swapChildren (a, b);
}
}
the only part that sucks is adding each movieclip to the array
Last edited by oPUPo; 04-01-2009 at 08:50 PM.
Reason: found my own answer elsewhere
-
Senior Member
The functions there should work if you just copy+paste them into a frame, and then call it...
WIP-ZOMBIES
I love vegetarians! More meat for the rest of us!
-
i just get an error when i call it with sortZ()
1136: Incorrect number of arguments. Expected 1.
-
Senior Member
Well, read the error! You aren't passing any arguments to the function! You need to pass the parent display object to it. If you want every single object in your .swf to be sorted, then pass 'this' to the function: sortZ( this);
Otherwise, you need to nest all of your game objects inside one big displayObject.
P.
WIP-ZOMBIES
I love vegetarians! More meat for the rest of us!
-
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|