# OpenGL 2D Depth Perception

I have a 2D RPG game written in Java using LWJGL. All works fine, but at the moment I'm having trouble deciding what the best way to do depth perception is. So , for example, if the player goes in front of the tree/enemy (lower than the objects y-coordinate) then show the player in front), if the player goes behind the tree/enemy (higher than the objects specific y-coordinate), then show the player behind the object.

I have tried writing a block of code to deal with this, and it works quite well for the trees, but not for the enemies yet. Is there a simpler way of doing this in LWJGL that I'm missing?

• What specific problem do you have with the enemies, and what algorithm are you using? Also could you show us a movie or picture where we can see what kind of effect you would like? (Castle Crashers comes to mind although that is '2.5D') – Roy T. Apr 4 '12 at 11:38
• Just went through the prosses of taking screen shots and posting them, to find out new members cant post images. Damn. Im using an algoritm i wrote, that basicaly cheks if the players y position is lowr or higher than the tree. I wanted to know if there was an es ier way, using LWJGL. Sorry, its hard to explain without an image to show =/ EDIT: I guess a good example would be the Pokeymon game for gameboy (if you have ever played/seen it). If the player went 'in front' of a object, then the game would draw the player first, and if behind the object, the object would be drawn first – Stephen James Apr 4 '12 at 12:31
• You can't? Hmm, I haven't played pokemon for a long time, maybe you can post some links to screen shots? – Roy T. Apr 4 '12 at 12:42
• youtube.com/watch?v=gJfbApaxJx0 If you watch this from 1:12 to 1:18, then the player comes out of a house, and is in front of it, but then moves forward and is behind another house, then walks around it, and then is in front of it. This is what I am trying to accomplish – Stephen James Apr 4 '12 at 12:51
• Ah IC now, I think they fake that effect entirely by py using the draw order. The houses are probably made for a few different sprites. Some of the sprites are drawn before your character is drawn. Then your character is drawn so it appears over it. Then finally the last parts of the house are drawn which could overlap the player and should appear on top of him. So alpha-blending (for transparency) and sorting objects to some given Z-order will do the trick for you. – Roy T. Apr 4 '12 at 14:13

I gather you are making an isometric 2D game? You could draw the background first, then sort all sprites (player, enemies, trees) by Y-coordinate and draw them in back-to-front order.

This is very similar to Eric's answer; just elaborated a bit more.

Firstly you should draw your background (graphics that do not obscure anything) first - so as an example this would be your grass, plants, sand etc.

Next you take your foreground (graphics that do obscure) in addition to your entities (player, enemies, etc.) and draw them from the top of the screen downwards. To do this you would essentially sort them according to their Y co-ordinate and then draw them from least to biggest.

In addition I would give each tile/entity a YRenderOffset field (that does not participate in the sorting) that would allow you to, for example, play havoc with the 'darkness' of a door so that it seems as though your character is walking through it: in this specific case the 'darkness' sprite would be physically located above where it appears (basically behind the house) with a YRenderOffset that corrects it back to where it should appear when rendered. You could invert this concept entirely by instead having a field called YSortOffset that would participate in the sorting and not the rendering.

The above two paragraphs can be rendered by the same code entirely. This gives rise to the concept of layers: so you would have the background and foreground layers and they would be rendered exactly the same way. You would then be able to add additional layers at some point in the future (a cloud layer?).

Correct me if I'm wrong, but the gist of your drawing routine is:

public void draw_frame() {
draw_world();
draw_character();
draw_enemies();
}


You will need to make it a bit more sophistocated.

Two approaches come to mind:

(1) make everything drawable in your world a subclass of some base class DrawableThing, say. Give it x, y and z accessors. use z to set the height of the thing. To draw a frame, collect all of the drawable things into a great big array, sort the array by, say, z then y, and then draw them in order. Sorting in Y ensures that (I am assuming you a are using a sort of semi-overhead look like the style of games of the SNES era) when thing A is on the same "level" (z) as thing B but is above it (y), thing B probably needs to be drawn on top of thing A as it will overlap it in the view.

This could result in a big array to sort with a lot of objects, so if you can, group some of the objects together into chunks (the flat ground is a good candidate) that can be drawn in one go.

(2) Use opengl to draw in quasi-3d and let the GL take care of the layering for you: set up an isometric perspective projection that makes your world look the way you want it to, then turn on depth testing and draw everything with a Z coordinate for how high it should be. It may need to be tweaked a bit for certain objects depending on how you model your sprites/images, but it will work.

As stated previously, layering is done in LWJGL by drawing everything in a certain order. I'd like to add a little to the responses people have given to answer your specific question:

" if the player goes in front of the tree/enemy (lower than the objects y-coordinate) then show the player in front), if the player goes behind the tree/enemy (higher than the objects specific y-coordinate), then show the player behind the object"

As stated above, you'll want to draw using a method that does things in order of bottom to top.

I've been working on this issue myself for a while.

And I think I have a solution. You'll want to create a draw order for each entity (tree, enemy, player, etc).

The draw order will be given priority using the entity's Y-Value.

So We'll draw things at a greater Y Distance BEFORE those of a Lesser.

Remember that Y Distance starts at the top left then goes down as the Y value increases.

So if we have T= tree, and x= player then

if x is behind T, T will be drawn after x (ie, ontop of x)

and if x is in front of T, T will be drawn before x (ie, behind x)

To clarify, we'll draw things sort of like this.

• World();
• For(y= 0; y < Grid.Size(); y++)
• DrawEntitiesByRow(y);

This is mostly what I'll be doing with an Isometric game I've been doing. Of course, there's more details because I have to draw the floor before the walls, and other things. This is all situational to your needs.