A Flash Developer Resource Site

Results 1 to 16 of 16

Thread: Depth Swapping in as3

  1. #1
    Senior Member AzraelKans's Avatar
    Join Date
    May 2002
    Location
    Hell... with frequent access to heaven ;)
    Posts
    409

    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.

  2. #2
    Senior Member tonypa's Avatar
    Join Date
    Jul 2001
    Location
    Estonia
    Posts
    8,223
    So u got 3 clips on stage and you want to switch char sprite between those 3?

  3. #3
    will i ever get it?
    Join Date
    Feb 2004
    Posts
    707
    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)

  4. #4
    Senior Member
    Join Date
    May 2006
    Location
    Manhattan
    Posts
    246
    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;
    	
    }

  5. #5
    Senior Member AzraelKans's Avatar
    Join Date
    May 2002
    Location
    Hell... with frequent access to heaven ;)
    Posts
    409
    Thanks new black thats exactly what I needed

  6. #6
    Senior Member
    Join Date
    May 2006
    Location
    Manhattan
    Posts
    246
    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 )"

  7. #7
    Knows where you live
    Join Date
    Oct 2004
    Posts
    944
    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

  8. #8
    Senior Member
    Join Date
    May 2006
    Location
    Manhattan
    Posts
    246
    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

  9. #9
    Junior Member
    Join Date
    Jan 2008
    Posts
    2

    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.

  10. #10
    Senior Member chriserrorplain's Avatar
    Join Date
    Aug 2002
    Location
    london village
    Posts
    623
    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

  11. #11
    Member
    Join Date
    Jun 2007
    Posts
    64
    Quote 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?

  12. #12
    Junior Member
    Join Date
    Apr 2009
    Location
    UK
    Posts
    10
    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

  13. #13
    Senior Member Pazil's Avatar
    Join Date
    Sep 2006
    Location
    Ontario, Canada
    Posts
    913
    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!

  14. #14
    Junior Member
    Join Date
    Apr 2009
    Location
    UK
    Posts
    10
    i just get an error when i call it with sortZ()

    1136: Incorrect number of arguments. Expected 1.

  15. #15
    Senior Member Pazil's Avatar
    Join Date
    Sep 2006
    Location
    Ontario, Canada
    Posts
    913
    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!

  16. #16
    Registered User
    Join Date
    May 2013
    Posts
    1
    http://www.sterlope.com/swapping-depths-in-as3/

    Check out this example.. its real good..

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center