00:00
00:00
Newgrounds Background Image Theme
Upgrade Your Account!

HO HO HOPE you become a Newgrounds Supporter this year!

We're working hard to give you the best site possible, but we have bills to pay and community support is vital to keep things going and growing. Thank you for considering!

Become a Supporter so NG can see another Christmas!

AS3: Arranging depths in Y

530 Views | 2 Replies
New Topic Respond to this Topic

AS3: Arranging depths in Y 2023-12-08 12:36:48


AS3 main


for my game it was necessary to correctly arrange all the MovieClips by depth, but there were many problems and so I did not find a solution, and I wrote myself, all that is needed for this is arranging everything along Y, the more Y (the zero coordinate in as3 is on top, which means we have Y going down) the more depth, and vice versa, the less Y the less depth


this code must be made either a module or a MovieClip, if you want to add MovieClips, add them by class, as you can see in the updateDepths() function in if()

package {
  import flash.display.*;
  import flash.events.*;

  public class DepthY extends MovieClip {
    private var mc:DisplayObject;

    public function setDepth(obj:DisplayObject):void {
      var depth:int = Math.floor(obj.y);

      if (depth < 0) {
        depth = 0;
      } else if (depth >= obj.parent.numChildren) {
        depth = obj.parent.numChildren - 1;
      }

      obj.parent.setChildIndex(obj, depth);
    }

    public function updateDepths():void {
      if (parent) {
        var objects:Array = [];

        for (var i:int = 0; i < parent.numChildren; i++) {
          var obj:DisplayObject = parent.getChildAt(i);

          if ((obj is hitBoxPlayer || obj is asClass || obj is gadjetHit) && obj != this && obj.parent == parent) {
            objects.push(obj);
          }
        }

        objects.sortOn("y", Array.NUMERIC);

        for each (var sortedObj:DisplayObject in objects) {
          setDepth(sortedObj);
        }
      }
    }

    public function DepthY() {
      addEventListener(Event.ENTER_FRAME, onEnterFrame);
    }

    private function onEnterFrame(event:Event):void {
      updateDepths();
    }
  }
}

this code uses Event.ENTER_FRAME so be careful


A couple changes/suggestions/questions I noticed...

var depth:int = Math.floor(obj.y);

Calling Math.floor() on something that'll anyways be stored as an int is probably unnecessary; since calling static methods is slow, best avoid it unless there's a good reason to.


I guess you're implementing this as a function that can be called by any movieclip that you want to be stacked by Y? That is, if you have 3 objects that need to be stacked by Y, then they should all have DepthY somewhere in the inheritance chain (e.g. X extends DepthY)?


If that's the case, it's probably much better to make the parent container manage its children rather than have the children manage themselves. This way, rather than calling updateDepths once per object in the container, it can be called just once -- by the parent container.


That's not to say that you can't have the child movieclips manage themselves -- it's possible to have your cake here and eat it too. By adding a custom Event listener (e.g. "REARRANGE" or something) to the parent container, you can have the child movieclips dispatch these events whenever they move, for example. Then, the parent container will call updateDepths in the next ENTER_FRAME (and immediately remove the ENTER_FRAME listener so that it doesn't need to be called when nothing's changed).


The benefit of this method is that even if there are 200 objects in the parent container, you'll only call updateDepths once, because all the REARRANGE event would do is to tell the container to eventually call updateDepths. Furthermore, you'll be achieving the same outcome in a more modular manner - you won't be bound to inheriting from DepthY in this case - so it'll work even with e.g. Sprite or Shape derived objects (although for the latter you'll have to create an EventDispatcher instance since Shape doesn't have one by itself).


The downside is that each of the downstream classes (e.g. asClass) will need to have code to dispatch the REARRANGE event, but I don't really see how that's too different from the current method, as you will anyways need to know when to update the depths.


Slint approves of me! | "This is Newgrounds.com, not Disney.com" - WadeFulp

"Sit look rub panda" - Alan Davies

BBS Signature

Response to AS3: Arranging depths in Y 2023-12-29 06:11:31


At 12/29/23 05:58 AM, Gimmick wrote:A couple changes/suggestions/questions I noticed...
Calling Math.floor() on something that'll anyways be stored as an int is probably unnecessary; since calling static methods is slow, best avoid it unless there's a good reason to.

I guess you're implementing this as a function that can be called by any movieclip that you want to be stacked by Y? That is, if you have 3 objects that need to be stacked by Y, then they should all have DepthY somewhere in the inheritance chain (e.g. X extends DepthY)?

If that's the case, it's probably much better to make the parent container manage its children rather than have the children manage themselves. This way, rather than calling updateDepths once per object in the container, it can be called just once -- by the parent container.

That's not to say that you can't have the child movieclips manage themselves -- it's possible to have your cake here and eat it too. By adding a custom Event listener (e.g. "REARRANGE" or something) to the parent container, you can have the child movieclips dispatch these events whenever they move, for example. Then, the parent container will call updateDepths in the next ENTER_FRAME (and immediately remove the ENTER_FRAME listener so that it doesn't need to be called when nothing's changed).

The benefit of this method is that even if there are 200 objects in the parent container, you'll only call updateDepths once, because all the REARRANGE event would do is to tell the container to eventually call updateDepths. Furthermore, you'll be achieving the same outcome in a more modular manner - you won't be bound to inheriting from DepthY in this case - so it'll work even with e.g. Sprite or Shape derived objects (although for the latter you'll have to create an EventDispatcher instance since Shape doesn't have one by itself).

The downside is that each of the downstream classes (e.g. asClass) will need to have code to dispatch the REARRANGE event, but I don't really see how that's too different from the current method, as you will anyways need to know when to update the depths.


I don’t think that anyone who doesn’t know as3 well needs to work with it, in any case, this is a working way to write code, a lot of things can be done if you just put !YourClass and such, just if you read the code, you can easily modify it