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\$
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.                     
}
| improve this answer | |
\$\endgroup\$
  • \$\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\$ – Martin Frank Jan 9 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;
        }
     }

};
| improve this answer | |
\$\endgroup\$
  • 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\$ – Daniel_1985 Jan 7 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\$ – Martin Frank Jan 8 at 5:11
  • \$\begingroup\$ @Daniel_1985 sorry for being so late ^_^ the OP helped even itself =) \$\endgroup\$ – Martin Frank Jan 9 at 6:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.