Search code examples
actionscript-3flashmovieclipflash-cs6

AS3: How to control which MovieClip is displayed over which


I'm making a game, in which some enemies are spawned in the right side of the screen, and then moving towards the left side of the screen. To get a little variation, the enemies are randomly spawned a little bit differently on the y-axis.

the problem: So I'm aware, that the last added MovieClip gets displayed on top of the other MovieClips. But I need a method, so that no matter what time it was added, the MovieClip that is lower on the y-axis always gets displayed on top of MovieClips that are higher on the y-axis. The reason is that otherwise it messes with the illusion of horizont in the game, since the MovieClips higher on the y-axis is supposed to look as if they are further away, than MovieClips lower on the y-axis.

I hope I'm making sense. Thanks in advance!


Solution

  • You need to sort them all based off of the y position, then set their index in the parent based off the sort order:

    This function will take all the children of a container/parent, and sort them based off the y position.

    function sortAllZ(container:DisplayObjectContainer):void {
        //build an array of all the objects:
        var list:Vector.<DisplayObject> = new Vector.<DisplayObject>();
        var i:int = container.numChildren;
        while(i--){
            list.push(container.getChildAt(i));
        }
    
        list.sort(sortZ);
    
        for(var i:int=0;i<list.length;i++){
            container.addChild(list[i]);
        }
    }
    
    function sortZ(a:DisplayObject, b:DisplayObject):Number {
        return a.y - b.y;
    }
    

    Since you'll likely be running this code every frame (assuming the y position of your objects changes over time), it would be more efficient to keep an array/vector of all your objects you want sorted. (instead of recreating a new one everytime you want to sort). If that's the case, you can just do:

    //where list is your vector/array, and container is the parent of items
    function sortAll(){
        //sort the vector/array using the custom sort method defined below
        list.sort(sortZ);
    
        //now loop through that array and add the children in that order
        for(var i:int=0;i<list.length;i++){
            container.addChild(list[i]);
        }
    }
    
    //if you are using an array and not a vector, take out the :DisplayObject type declarations
    function sortZ(a:DisplayObject, b:DisplayObject):Number {
        return a.y - b.y;
    }