20
Jun
11

Isometric Z-Sorting


By the time you read this post, you’ve probably spent a good amount of hours googling for the perfect z-sorting solution for your isometric game. If not, good for you! This post might save you some major headaches.

If you have items in your game that take up more than one cell, this is the solution you were looking for. It works with rectangular items of all sizes, 2×2, 4×1, 1×3, etc. L-shaped items won’t work though.

First I have to give a big Thank You to Jobe Makar. The code in this example is based on the z-sorting approach in his book ‘ActionScript for Multiplayer Games and Virtual Worlds’: in order to determine the correct display order we loop through the array of items and insert them one by one into a new array depending on their row and column:
for ( var i:uint = 0; i < _aSortableItems.length; i++ ) {
   objItem = _aSortableItems[i];
   if ( (objNewItem.uiCol <= objItem.uiEndCol) && (objNewItem.uiRow <= objItem.uiEndRow) ) {
      _aSortableItems.splice( i, 0, objNewItem );
      bAdded = true;
      break;
   }
}
if ( !bAdded ) _aSortableItems.push( objNewItem );

There was one little problem with this approach though. Depending on the order in which items are inserted, dependencies between items close to each other weren’t always correct.
I was able to correct this by sorting the array of items by their cell index from closest to farthest, before running the above code:
_aSortableItems.sort( sortByPos );
private function sortByPos( a:SortableItem, b:SortableItem ):int {
   if ( (a.uiRow * INC.WORLD_COLS + a.uiCol) < (b.uiRow * INC.WORLD_COLS + b.uiCol) ) {
      return( 1 );
   }
   else return( -1 );
}

And that’s pretty much all there is to it. This example runs pretty well with 1000+ items, which is probably more than the average game needs.

Click on the image below to see it in action, or download the source code here.


All artwork courtesy of Meteor Games, LLC

I tried to comment my source code as good as possible, but feel free to leave me a comment if you have any questions.


14 Responses to “Isometric Z-Sorting”


  1. June 20, 2011 at 4:22 pm

    Love it! I was just going to ask you about the code!!! :D

  2. 2 Bruce
    March 23, 2012 at 11:58 am

    Hey,

    I am looking forward to giving this a spin. Can you tell me if this works for any height of object or whether I would need to add that in?

    Thanks,

    Bruce

  3. 4 as3isolib
    March 24, 2012 at 11:17 pm

    does this account for items that are “transitioning” from one cell to another, say like an avatar character moving from pt A to pt B while navigating around obstacles?

  4. 6 as3isolib
    March 25, 2012 at 8:36 pm

    actually all I see is items snapping into and out of place, not tweening to a new position. I am not sure if it’s a flash player version or what. Should they be tweening? Thanks for the fast reply btw.

    This would greatly improve performance on the as3isolib.v1 if this works as I am hoping it does.

    • 7 obrodhage
      March 27, 2012 at 1:11 am

      Oh, I see what you’re saying. There’s no tweening in this example, just random ‘teleporting’ ;)
      That moment when an avatar changes cells and its z-value changes, is always tricky. Keeping the cell width and height as small as possible is one way to keep weird depth-effects with moving objects to a minimum.

      • 8 Bruce
        March 31, 2012 at 5:57 pm

        Could you treat the avatar as a 2×1 object that encompasses the cell the avatar is on and the one that it is transitioning too? Would that not prevent sorting issues when it transitions?

        • 9 obrodhage
          April 24, 2012 at 8:36 am

          Hey Bruce, sorry for the late response. That’s an interesting idea,
          but in order for it to work in all directions, you’d have to set up
          the avatar as a 3×3 object. In that case the avatar wouldn’t be able
          to walk up close to an object though.

          • 10 Bruce
            November 18, 2012 at 3:11 pm

            Your response wasn’t as late as this one :)

            Instead of making the object a 3×3, could you resize the object based on the direction it is currently walking? I think that would work.

  5. 11 as3isolib
    March 27, 2012 at 2:31 pm

    based on this statement:

    “in order to determine the correct display order we loop through the array of items and insert them one by one into a new array depending on their row and column”

    AND based on your last comment

    “Keeping the cell width and height as small as possible is one way to keep weird depth-effects with moving objects to a minimum.”

    could you safely reduce the cell width and length down to 1px and assume this algorithm would still work?

    • 12 obrodhage
      March 28, 2012 at 2:31 pm

      Funny you should ask. I did exactly that in my last project. It works, but you might end up with a huge array, depending on the width and height of your level.

  6. 13 Felipe
    April 26, 2012 at 3:22 pm

    Hey,

    Thank you very much for the code and now I finally understood why my algorithm wasn’t working! Running the sort function in an array and then running it again caused me unexpected behavior and your solution cleared that for me!

    Great Job. And, would mind if I ask where you work now? Hehehe :)

    Best Regards.


Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>