So im currently working on an RPG that has the player and the currently walk in front if all objects. What would be the best way to add a depth of field so that the player can walk infront of an object if they are infront of it and behind it if they are behind. I was thinking that i could just print two images for each item and have the correct one displayed depending on the players position
Fake it. Change the order of drawing objects (The moving ones) such that they’re drawn after the things that they are in front of, but before things they are in back of. If it’s an isometric game, this means you draw objects based on their Y value and that you draw tiles/floors/walls before other objects.
I’m not sure how “good” this will be for a Java 2D based engine though. Your idea of making several different sprites for the same object may work better (It’s certainly viable for a small number of variations) but the number of different sprites might be high if you have a lot of dynamic objects (Players moving, Monsters moving, dropped items, etc.).
The main difference is the cost trade off. The ‘Fake it’ could, on a map with a large number of dynamic objects, require more calls to draw. Your idea would require the same number of draw calls (one per tile/object) but it increases the number of sprites you need by around 2 (This is if EVERY object in the game has an overlap image). If there are more than just the player on the screen moving then this number could be drastically larger.
I, personally, can’t say which is better in a Java 2D environment but someone else might be able to. (Do note that at the same time it might not matter! Depending on the size of your drawing space-- the number of tiles/objects you’re drawing-- the difference might be small enough not to matter.)
If you had some sort of collection of all objects and entities (such as an ArrayList), then you could sort them prior to each render using a custom comparator, sorted by their z value (which as UprightPath has pointed out, this would likely be the y value).
I’m not sure what the performance would be like, but you could probably work out a few optimisations, particularly if the game is tile-based. (i.e. associating objects and entities with tiles, and only ‘depth sorting’ for visible tiles).
Anyway, that’s generally how I’ve got around it in the past. Although I’ve only ever tried it in small, menial projects. No idea how it would go with a decent sized project.
Yeah, if you are talking about 2D java, a simple array to change the draw order of the Y elements should be enough.
If the main character is the only entity moving in the world and the camera follows it, you can actually focus your drawings around the character. In other words, you leave a small radius around the character untouched, and then only redraw the elements around the character that need the depth.
If you have many moving entities, an array based on Y location can work. I like this method a lot because when you are dealing with many entities, you can reorder the entities on the fly as you need them drawn.
As the above poster said, you have to fake it. It is all about the draw order and positioning that shows depth.
Im confused as to how i could reorder the objects in an array list. Any source?
Here’s what appears to be an alright tutorial:
http://www.vogella.com/tutorials/JavaCollections/article.html#collectionssort
Essentially you’ll need to create and use your own implementation of this:
http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html
If you need more resources to work with, google “Java comparators”, “java sorting ArrayLists” or similar. There’s a fair bit out there on the subject.
PS. Here is a quick and dirty comparator I previously used to sort some ‘Sheep’ objects based on their y position:
import java.util.*;
public class SheepZComparator implements Comparator<Sheep> {
@Override
public int compare(Sheep lhs, Sheep rhs) {
if(lhs.yPos < rhs.yPos) {
return -1;
} else if (lhs.yPos > rhs.yPos) {
return 1;
} else {
return 0;
}
}
}
Then in the update loop, prior to rendering, I call:
Collections.sort(sheep, comparator);
Where ‘sheep’ is an ArrayList of Sheep, and ‘comparator’ is the aforementioned Comparator. In your case, you may want all game objects and entities to implement a common interface, and base your comparator on that.
I ended up using my own wersion where i just drew the image correspondent to the players position but thankyou for all the advice