## Depth Sorting in an Isometric World

While creating objects in an isometric world, you may encounter an issue where objects appear in front of others when they are not supposed to:

Clearly, the sheep (enemy) is standing on a tile behind the girl (player) and should therefore appear behind the girl.  This is where depth sorting comes into play.

What we’re basically going to do is switch the “z-depths” of the girl/player and the sheep/enemy based on their y values.  Objects with the greatest y will have the highest priority on the “z-depth” list.  Since we only have two objects in the world, we can simply compare their y’s and swap their “z-depths” if needed.  (I quote “z-depths” because in a 2D world, we don’t really have z, but it’s more like “priorities” — the ones with highest priority or highest index will appear more to the front on the screen.)

Luckily, since I am using EaselJS, swapping “depths” is quite easy; use stage.getChildIndex(displayObject) to find an object’s (i.e. a Sprite’s) index in the display list, and stage.swapChildren(displayObject1, displayObject2) to swap two objects’ (i.e. two Sprites’) indexes.  (In my isometric world, I used Sprites, and Sprite extends Display Object.)  The higher the index of an object in the display list, the higher its priority, and the more to the front the object will be.  In the movePlayer() function, I have something like this, and movePlayer() gets called in every frame:

```if (player.y > enemy.y) {
if (stage.getChildIndex(player) < stage.getChildIndex(enemy)) {
stage.swapChildren(player, enemy);
}
} else if (player.y < enemy.y) {
if (stage.getChildIndex(player) > stage.getChildIndex(enemy)) {
stage.swapChildren(player, enemy);
}
}```

Perhaps I will look into this a bit more efficiently though, and think about how to not have to compare the y’s on every frame, especially since the enemy is not moving.  But I guess it becomes a bit more complicated when the enemy does move, and the comparison on every frame becomes more needed, so I guess I will leave it as is for now…

So I’ve been using EaselJS 0.5.0, but then decided to upgrade to the latest version as of this blog, 0.7.0, while hoping for some performance boosts.  After doing so, nothing worked.  Here were the problems I had and how I fixed them —

Problem #1: When running my app, I got an error in the console: “BitmapAnimation is deprecated in favour of Sprite. See VERSIONS file for info on changes.”

Solution: Luckily, it wasn’t a big deal at first.  I just needed to rename “BitmapAnimation” to “Sprite”.  So:

`bmp = new createjs.BitmapAnimation(img);`

became

`sprite = new createjs.Sprite(spriteSheet);`

But my sprite’s frames remained at 0.  My character is supposed to face different directions based on where she is going.  So I had to make more changes and use “gotoAndStop()” instead of “currentFrame”:

`context.player.currentFrame = 2;`

became

`context.player.gotoAndStop(2);`

gotoAndStop()… sounds like ActionScript 3?  🙂

And lastly, the way I wrote the click event when clicking on the sprite had to change:

`bmp.onClick = function(event) {`

became

`bmp.on('click', function(event) {`

Problem #2:  There was another error in the console; this one was related to the “tick” event, which is like the heartbeat of the application – “Uncaught TypeError: Object function (){throw”Ticker cannot be instantiated.”} has no method ‘addListener'”

Solution:  I looked at the EaselJS Docs and realized that addListener wasn’t a function in Ticker anymore, but addEventListener was, and it accepted “tick” as an argument, as well as a function to call once “tick” gets triggered.  I called that function handleTick().  So:

`createjs.Ticker.addListener(Main);`

became

`createjs.Ticker.addEventListener('tick', handleTick);`

and

`var tick = function(dt, paused) {`

became

`var handleTick = function(event) {`

I actually liked this change; it makes a lot more sense: on every tick, call the handleTick() function.

And TA-DA!!  Everything worked again.

So after poking around the EaselJS Docs and some trial and error, I was able to find the solutions above.  Note to self: Don’t upgrade anymore! (Watch me upgrade again anyway lol!)  😛

* EDITED – 11 OCT 2013 *

– I edited a code snippet above to eliminate confusion; Sprite accepts a spriteSheet as a parameter in its constructor. (Thanks, Sebastian!).

– Check out the VERSIONS.txt for a detailed listing of major updates.  HA, maybe I should read the error messages more carefully – “See VERSIONS file for info on changes.”  (Thanks, CreateJS!).