SOLVED - ISOMetric Sort Order Issue

Hi there.

I am trying to sort objects on an ISOMetric map to get the correct drawing order. I have tried using the below example which works perfect when all the objects are the same Height and Width but as soon as the Height or Width changes then this method is no longer accurate as seen in the pictures.

I have tried searching the forums and internet for how others have overcome this issue and the answers seem to be use OpenGL etc… I am sure there has to be another way to accomplish this with some math… If anyone knows of a way to correct this issue or can point me in the right direction it would be appreciated.


package com.deadendertainment.chat.objects;

import java.util.Comparator;

import com.deadendertainment.chat.ChatGame;
import com.deadendertainment.chat.characters.Player;

/**
 * 
 * @author Fsig
 *
 */
public class GameObjectComparator implements Comparator<GameObject>{

	@Override
	public int compare(GameObject e1, GameObject e2) {
		return (int) ((e1.getX() - e2.getX()) - (e1.getZ() - e2.getZ()) - (e1.getY() - e2.getY()));
	}

}

Example picture one:

Example picture two:

  1. first sort by X axis
  2. then sort (whatever is on the same row) by Z axis
  3. then sort (whatever is on the same tile) by Y axis (height)

This means that for every tile you visit, you draw the items from lowest to highest.

Thanks, ill give this a go.

Depends a bit on how you are storing/drawing your objects. If you only have a 2d array, e.g., you can simply draw them in order from lowest to highest like Riven suggests. But glancing at your comparator, simply sorting by depth (x+y+z) should work:

   @Override
   public int compare(GameObject e1, GameObject e2) {
      int a = e1.getX() + e1.getY() + e1.getZ();
      int b = e2.getX() + e2.getY() + e2.getZ();
      return (a < b) ? -1 : 1;
   }

The above method yields the same results.
I haven’t been able to work out a good way of sorting by rows and such yet.

The Objects are stored in an ArrayList and then to render I use a for loop as seen below.


for(GameObject go : gameObjects)
				go.render(g);

Resolved by comparing the X then the Z as seen below like mentioned above. (Ignoring Y altogether)
Well this at least seems to fix the height issue, I will have to test width when I make a object for one.


@Override
	public int compare(GameObject o1, GameObject o2) {
		if(o1.getX() < o2.getX())
			return 1;
		else if(o1.getX() > o2.getX())
			return -1;
		else
			return 0;
	}

	@Override
	public int compare(GameObject o1, GameObject o2) {
		if(o1.getZ() < o2.getZ())
			return -1;
		else if(o1.getZ() > o2.getZ())
			return 1;
		else
			return 0;
	}

And then in my update method I just call them in order.


			Collections.sort(gameObjects, goX);
			Collections.sort(gameObjects, goZ);

Picture one:

Picture two:

Thanks Guys :smiley:

Try this:

  @Override
   public int compare(GameObject e1, GameObject e2) {
      int a = e1.getX() + e1.getZ();
      int b = e2.getX() + e2.getZ();
      if (a < b) return -1;
      if (a > b) return 1;
      // if same, order by Y value
      return e1.getY() < e2.getY() ? -1 : 1;
   }