1
\$\begingroup\$

I'm fairly new to the world of coding, and there's probably a simple solution here. I made this array (the actual one is more complex since it includes everything I have so far) for the y values of every object that needs to be rendered, but I don't know how to use it to keep track of which y values correspond to which object in order to draw them from lowest y value to highest y value.

int [] yValues = {deer.getY(), sprite.getY(), tree.getY()+150};
    Arrays.sort(yValues);

The deer just randomly walks around, and the player (sprite) is controlled by arrow keys. I added to the y value of the trees so that characters that walk around would stay behind them.

Right now I've hard-coded the layering, depending on when the sprite is in front of or behind the tree (hair and skin y positions are dependent on the y position of the sprite, which is why I didn't include them in the yValues array).

//Printing order
    if (sprite.getY() < tree1.getY()+150) { //if the player is behind the tree

        g2d.drawImage(deer.getImage(), deer.getX(), deer.getY(), this);

        g2d.drawImage(sprite.getImage(), sprite.getX(), 
            sprite.getY(), this);
        g2d.drawImage(skin.getImage(), sprite.getX(), 
                sprite.getY(), this);
        g2d.drawImage(hair.getImage(), sprite.getX(), 
                sprite.getY(), this);

        //the tree is drawn after everything else   
        g2d.drawImage(tree.getImage(), tree.getX(), tree.getY(), this);
    }


    if (sprite.getY() >= tree1.getY()+150) { //if the player is in front of the tree

        //the tree is drawn before everything else
        g2d.drawImage(tree.getImage(), tree.getX(), tree.getY(), this); 

        g2d.drawImage(deer.getImage(), deer.getX(), deer.getY(), this);

        g2d.drawImage(sprite.getImage(), sprite.getX(), 
            sprite.getY(), this);
        g2d.drawImage(skin.getImage(), sprite.getX(), 
                sprite.getY(), this);
        g2d.drawImage(hair.getImage(), sprite.getX(), 
                sprite.getY(), this);
    }

From here, how would I use the yValues array to order the drawing?

[I found this post helpful to what I'm trying to do] (Java Slick2d image depth/layering).

The above code works for the tree enter image description here

But not for other objects, like this deer:

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

This is what I figured out and it works, but Martin's answer is probably a lot more efficient.

I went ahead and used the array of y values that I made, and then below it made a bunch of code segments like this:

for (int i = 0; i < yValues.length; i++) {
if (sprite.getY() == yValues[i]) {

            g2d.drawImage(sprite.getImage(), sprite.getX(), sprite.getY(), this);}
//And so on for each sprite.                     
}
\$\endgroup\$
1
  • \$\begingroup\$ i core you hit the same idea - i didn't make it in time to provide the complete answer, but i'm glad you found a way!!!! \$\endgroup\$ Jan 9, 2020 at 5:59
1
\$\begingroup\$

instead of trying to identify the drawing order for each sprite itself you should create a proper drawing order first of.

List<Sprite> sprites;
Comparator<Sprite> topLeftComparator;

void draw(Graphics graphics){
    sprites.sort(topLeftComparator); //create proper drawing order first
    for (Sprite sprite: sprites){
        sprite.draw(graphics); //then draw all sprites
    }
}

Details

let's assume you have a class (better: an interface) named Sprite. That Sprite allows you to set the position of the sprite (and read it back) and to draw it

interface Sprite {

    //set & read back position
    void setPostion(int x, int y);
    int getX();
    int getY();

    //draw
    void draw(Graphics graphics); 

}

you can now create and position all Sprites that you want to draw. Add them to your list:

Sprite tree, player;
List<Sprite> sprites;
...
//set postion
tree setPosition(2,4);
player.setPosition(2,3);

//and add to the list
sprites.add(tree);
sprites.add(player);

then you simply sort that list and draw your sprites according to the order of the list (as mentioned above).

Sorting

the magic happens when you sort the list. The sorting algorithm that is used sorts the sprites first by y-value (aka each row) and than by x-value (by column). That results in an top/left->bottom/right order.

Comparator<Sprite> topLeftComparator = new Comparator<Sprite>() {

    @Override
    public int compare(Sprite s1, Sprite s2) {
        int compareValueOfRow = Integer.compare(s1.getY(), s2.getY());
        if (compareValue == 0){ //0 means y is equal for both
            //the return according to x-pos
            return Integer.compare(s1.getX(), s2.getX()); 
        }else{
            return compareValue;
        }
     }

};
\$\endgroup\$
3
  • 1
    \$\begingroup\$ How would such comparator function look like? Since OP is at a beginner-level of programming, it might help to show an example of such function. \$\endgroup\$ Jan 7, 2020 at 22:12
  • \$\begingroup\$ Sorry for such a short answer, i was in a hurry when i wrote that answer. I'll add these details, when i'm back at my office \$\endgroup\$ Jan 8, 2020 at 5:11
  • \$\begingroup\$ @Daniel_1985 sorry for being so late ^_^ the OP helped even itself =) \$\endgroup\$ Jan 9, 2020 at 6:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .