Dynamic Z ordering

  • This is less of a "How do I" and more of a "can I do this more optimized?"

    I have a fairly simple event setup for dynamic z ordering using Y pos on a family of objects:

    + System: Every tick

    ----+ Zorder: Is visible

    ----+ System: For each Zorder

    ----+ System: Pick Zorder where Zorder.?Y > PlayerController.?Y

    -----> Zorder: Move in front PlayerAnim

    ----+ System: Else

    ----+ Zorder: Is visible

    ----+ System: For each Zorder

    ----+ System: Pick Zorder where Zorder.?Y < PlayerController.?Y

    -----> Zorder: Move behind PlayerAnim

    This works well for my needs, and it handles it fairly well, i think. 67 sprites (all animated braziers) settles at around 5% CPU usage while walking up and down the layout constantly.

    What I'm wondering is if anyone has done, or knows of something, more efficient CPU wise to do this? or is this about as clean as it can get?

    quickedit. realized the pick should be before the loop. swapped them around, and its to about 4% now, which is nice, but main question still stands, thanks!

  • Add everything that needs z-ordering to 1 family.

    Every 0.1 second

    Z-order is on screen

    For each z-order order by z-order.Y ascending

    Z-order move to top of layer

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • thanks lennaert dont know why i didn't think of using x based seconds to do that computation. the exact method you posted certainly helped, though I had to change it a bit for my use case. I ended up going with

    + System: Every 0.1 seconds

    + Zorder: Is on-screen

    ----+ System: Pick Zorder where Zorder.?Y > PlayerController.?Y

    ----+ System: For each Zorder order by Zorder.?Y ascending

    -----> Zorder: Move in front PlayerAnim

    ----+ System: Else

    ----+ System: Pick Zorder where Zorder.?Y < PlayerController.?Y

    ----+ System: For each Zorder order by Zorder.?Y ascending

    -----> Zorder: Move behind PlayerAnim

    to achieve my desired effect:

    I cant just move everything to the top layer, as it messes up when the player would walk in front of the objects, but your advice on the 0.1 seconds timer as well as using on-screen instead of is visible, and also along with using a for each ordered bought CPU usage down to a much better 2%. Im sure that it will scale much better on things like overworld maps as well.

  • i love using rex z-order plugin:

    http://c2rexplugins.weebly.com/rex_zsorter.html

    Unfortunately I dont know if that plugin would work, considering im on C3 and not C2. I also just enjoy figuring out how to do things without plugins and just using pure event sheets. that plugin did pop up in more than a few threads though!

  • Your welcome, rovacado. There are many variations of the zordering approach, as in your case, you just need to find one that suits your mechanic and setup well

    the 0.1 seconds interval is a very good one when it comes to performance btw, you can use it in many occasions.

  • Bring them into a family. Add an instance variable representing Y.

    + (no conditions)

    -> family: Set Y_Order to Self.?Y

    -> System: Sort family Z order by Y_Order

    And its done. Think they need to be on the same layer.

    Additional, if the player is the only moving thing, start with (player) Is overlapping (Family), update for family and player (player is not in the family picklist). Now you can execute this 1000 times in one tick, dont matter.

  • 99Instances2Go

    Didn't manage to make it work. Would you post a .capx, please ? Thanks in advance !

  • thanks lennaert dont know why i didn't think of using x based seconds to do that computation. the exact method you posted certainly helped, though I had to change it a bit for my use case. I ended up going with

    + System: Every 0.1 seconds

    + Zorder: Is on-screen

    ----+ System: Pick Zorder where Zorder.?Y > PlayerController.?Y

    ----+ System: For each Zorder order by Zorder.?Y ascending

    -----> Zorder: Move in front PlayerAnim

    ----+ System: Else

    ----+ System: Pick Zorder where Zorder.?Y < PlayerController.?Y

    ----+ System: For each Zorder order by Zorder.?Y ascending

    -----> Zorder: Move behind PlayerAnim

    to achieve my desired effect:

    I cant just move everything to the top layer, as it messes up when the player would walk in front of the objects, but your advice on the 0.1 seconds timer as well as using on-screen instead of is visible, and also along with using a for each ordered bought CPU usage down to a much better 2%. Im sure that it will scale much better on things like overworld maps as well.

    LIKE THIS...

    BUT HOW SOLVE THIS...

    CODE:

  • FWIW, using "move to front" or "move to back" in a loop is very inefficient. This is why we made the System 'Sort Z order' action - it's much more efficient for ordering lots of instances.

  • FWIW, using "move to front" or "move to back" in a loop is very inefficient. This is why we made the System 'Sort Z order' action - it's much more efficient for ordering lots of instances.

    Hi Ashley

    Ive just seen this.

    I supose it is to do with z-sorting every run of a loop compared to z-sorting all at the end

    So would it be correct to assume that this recommendation is also applicable to something like

    For Each "ZObject" > in order of instance variable Z (ascending) > move to XY

    ZObject move to bottom of layer

    (as this will process in order of individual instance Z variable,

    thus the objects will appear in the correct Z order naturally)

    so would actually be better to do like

    For Each "ZObject" move to XY

    then Sort all ZObjects together according to ivarZ

    So now they are moved first in any order then Z sorted all at once after the loop

    ?

    cheers

  • Changing Z order in a loop is inefficient because it changes the Z order repeatedly. The 'sort Z order' action is efficient because it does the sorting, then changes the Z order once at the end. So you should basically only use the 'sort Z order' actions for large numbers of instances. However if you just update the instance variable it uses in a loop, that's fine, because updating an instance variable doesn't itself change Z order.

  • Changing Z order in a loop is inefficient because it changes the Z order repeatedly. The 'sort Z order' action is efficient because it does the sorting, then changes the Z order once at the end. So you should basically only use the 'sort Z order' actions for large numbers of instances. However if you just update the instance variable it uses in a loop, that's fine, because updating an instance variable doesn't itself change Z order.

    Thanks, sorry yes I missed the "Move to Top/Bottom in my example above. (will edit)

    OK then, I am processing all the enemies and environmental objects in my game (pretty much everything you see on screen) in this inefficient way, every tick!

    (And here is me still being impressed with the performance !)

    Cheers

  • Nice!

    I was starting to see dips to 54 fps in current build when getting above 40 enemies on screen

    this simple change has taken me back to 60fps

    thanks !

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)