I'm having some unique trouble determining the order in which objects should be rendered, particularly in the case of when a player is behind a wall. I'll try and explain thoroughly, so prepare for a lot of information.
I render things back to front (as recommended here: Drawing Isometric game worlds) and that is, for the most part, simple enough. I determine what is in the back using a simple comparator:
private Comparator<Entity> spriteSorter = new Comparator<Entity>(){
public int compare(Entity e1, Entity e2){
if(e1.getPhysics().getY() > e2.getPhysics().getY()) return 1;
if(e1.getPhysics().getY() < e2.getPhysics().getY())return -1;
return 0;
}
};
This uses the hitbox of an entity to determine its render order, and it works flawlessly for entities with a rectangular hitbox (as almost all my characters do). The actual draw call looks like this:
ArrayList<Entity> spriteList = new ArrayList<>();
spriteList.add(player);
for(int i = 0; i < walls.size(); i++){
spriteList.add(walls.get(i));
}
Collections.sort(spriteList, spriteSorter);
for(int i = 0; i < spriteList.size(); i++){
spriteList.get(i).render(g);
}
Here's where things get tricky though, all my characters use an instance of Rectangle, and their ordering works with no problem at all, but my walls (due to the nature of an isometric game) cannot use a rectangle, and thus use a Polygon that fits their size.
See picture:
I have to use a Polygon because if I use a rectangle, I get a stupid unpassable space near the wall like so:
Unfortunately, due to the nature of polygons, there is no immediately apparent test to see if the player is in front or behind the wall. Line 3 seems to be a likely candidate as a test, but there are two triangles on either side of the wall that would pass the player.getPhysics.getY() > wall.getPhysics.getY()
test and mark him as in front, when he could be both in front and behind the wall.
So, how can I devise a test to tell me when he is behind the diagonal lines? The nature of Shapes and Polygons in Java seems to be limiting me a lot, but I'm sure there's a way to do it. I've played with points a lot, and getCenterY() has gotten fairly close, but it's still not perfect. The problem cases that arise with all of the methods I've tried look like this:
Actually behind, rendered in front
or this:
Actually in front, rendered behind.
Any one got any ideas?