Drawing order of Objects in an Arraylist

I didnt knew how to name this. But I got a class with multiple other classes that inherit from the main one.

Now when I clicking I can add one of the Objects to the Sketch and all the Objects are held withing an Arraylist.

The problem I have, is that I want to have them in a specific order. Lets say first I create a “Stone”. Now I want to create a “Lawn” underneath that stone. But when I click to create a Lawn its on top of the stone.

How can I fix that?

Here are the important parts of my code:

void setup () {
  size (1000, 700);

  gardenobjects = new ArrayList<GardenObject>(); //creates Arraylist
}

  //Add new Stone on click
  if (ButtonState == 1 && Gardening == true) {

    gardenobjects.add(new Stone(mouseX, mouseY, 50));
  }

void mousePressed() {
 //Add new Stone on click
  if (ButtonState == 1 && Gardening == true) {

    gardenobjects.add(new Stone(mouseX, mouseY, 50));
  }

  //Add new Lawn on click
  if (ButtonState == 2 && Gardening == true) {
    gardenobjects.add(new Lawn(mouseX, mouseY, 100));
  }
}
void draw() {

  for (int i=0; i<gardenobjects.size(); i++) {
    GardenObject g = gardenobjects.get(i);
    g.draw();
  }
}

let me know If you need more information of the code.

1 Like

The Lawn is underneath the stone when you first draw the lawn and then the stone.

You could give every object an Z value and

  • loop over the entire ArrayList and first draw all with 0 Z then
  • loop over the entire ArrayList again and draw all with Z 1
  • etc.

Or when you only have a small numbers of types, then just do the same and draw Lawn first, then draw Stone etc.

**Hey, and welcome to the forum! **

Great to have you here!

Thanks for the quick Answer!

But I think im not sure how to do that. How would I give Lawn for example Z=0 and Stone Z=1?

and how would I tell the programm to first draw the 0s and then the 1s?

let’s say you have an String type in the class

This is either “lawn”, “stone” etc.

before setup()

// Their ORDER must be from draw first to draw LAST
String[] typeList = {
"lawn", 
"stone",
"sand"
};

DRAW

for(String s : typeList) {
   for (GardenObject g = gardenobjects) {
       if(g.type.equals(s)) {
            g.draw();
       }
   }
}

Ahh thanks i think i understand that now. Though i dont think we are allowed to use that yet. We only got Arrays and Arraylists thats why I am confused as well because in our Lectures we havent discussed anything that could let me know how to achieve what I want yet we need to do that :smiley:

I only use Array / ArrayList and String

(and a short form of a for-loop, it works like for each String “s” in typeList do {…})

Of course you can also use your idea with a z value

Use a nested for loop like I did above and instead of checking for a String check for the Z

Then you need to bring a Z-Value into the class

    zValue = stoneZ;  // when you define Z values for stone and Lawn before setup()
    gardenobjects.add(new Stone(mouseX, mouseY, 50, zValue )); // change your constructor

DRAW

// here all Garden Objects with Z == 0 are drawn first, then all those with Z ==1, then Z==2 etc.
for(int allowedZ = 0; allowedZ < 4; allowedZ++) { // 4 is just a guess. 
   for (GardenObject g : gardenobjects) { // I had an error here first 
       if(g.z == allowedZ) { // check Z 
            g.draw();              // draw 
       }
   }
}
1 Like

Wow thanks yea that will work. I hope I understand it. I will try later.

This could also fix another problem I guess. Because I need to make it so that I can delete objects with a click as well. Currently when for example the grass is underneath a stone the grass also is deleted. But I think this way I can prevent it from happening.

Remark 1

instead of going over the entire list and each time search for a Z it would be faster to sort the entire list by Z and then just display it in the right Z order. But sorting in my experience is hard for a beginner

Remark 2

I am not sure this will prevent that.

If not:
Instead when you click on a field and there are e.g. three garden objects underneath, you have to check which one of those has the highest Z and delete only this one.

Which is in itself a bit tricky. Rough description: You need to store the highest Z as maxZ and compare against this and also store the index of the garden object with the highest Z (maxZ_Index) and after the loop delete the garden object with this index.

Yea, efficiency isnt important yet. But thanks for now I see if I can make it like that.

May I ask you if a problem occurs i cant fix?

Hey, of course you can!

I didn’t try it yet. But I see you wrote g.z == allowed

Wouldn’t that g.z mean that I need to make a new function inside of the class?

allowedZ is just the variable in the first for loop

You need to implement z in the class

Yea, is it as simple as implementing Z as the last variable of the Constructor so in my Stone class wich extends the GardenObject class I put:

  Stone(..., ..., ..., int z) {

    ...
    ...
    ...
    z =1
  }

I think so, yeah.

z must be in all classes and have the right value

It worked thank you so much that actually helped me understand all of this a lot more.

Now im gonna figgure how i do the deleting part

1 Like

It seems that I cant sort out how to use Z to define wich object im clicking…

for the detection if my mouse is over i use a Boolean inside the main class “Garden Object”

 boolean isInside (float mx, float my) {
    return x-s/2<=mx && mx<=x+s/2 &&
      y-s/2<=my && my<=y+s/2;
  }

x and y are the positions, s is the size and mx and my would be mouseX and mouseY.

to actually delete the Object im currently using this in the main program:

//Remove clicked Object
void mouseClicked() {

  if (ButtonState == 4) {

    for (int i=0; i<gardenobjects.size(); i++) {
      if (gardenobjects.get(i).isInside(mouseX, mouseY)) {
        gardenobjects.remove(i);
        i--;
      }
    }
  }
}

how could I use Z in there to only delete the first object my mouse is over?

That was what I tried to describe before with maxZ and so on.

Let me see…

We first loop over the entire thing and find the clicked tile with the highest Z.

Then after the for-loop we remove it.

(can’t test it here…)



//Remove clicked Object
void mouseClicked() {

  if (ButtonState == 4) {

    int maxZ= -100;  // store the highest Z as maxZ
    int maxZ_Index = -1;  // store the index of the garden object with the highest Z (as maxZ_Index)

    // search highest Z when multiple garden objects are underneath the mouse  
    for (int i=0; i<gardenobjects.size(); i++) {
      if (gardenobjects.get(i).isInside(mouseX, mouseY)) {
        if (gardenobjects.get(i).z > maxZ) {
          maxZ = gardenobjects.get(i).z; // store 
          maxZ_Index = i;
        }//if
      }//if
    }//for

    // -----

    // Evaluate the findings 
    //after the loop delete the garden object with this index.
    if (maxZ_Index > -1) { // found something?
      gardenobjects.remove(maxZ_Index); // Yes
    }//if
    //
  }//if
}//function

(by the way when drawing the garden objects: I wrote 4 there in the for-loop please replace with how many Z-values you really have (this +1, so when you have 0 and 1 as Z-values, you must go to < 2))

I’m gonna test that later this day. Thank you very much sir.

Yea 4 is actually already the proper number.

1 Like

the code definetely works. What I am wondering now if its possible to walk through that zMax loop the other way around? because right now when two of the same objects are above each other it deletes the one that has been placed first wich is the bottom one.

I also used your example to implement a drag and drop functionality. And the same problem occurs, because when I drag one Object over another with the same Z value wich has been created before the one im dragging it switches over that one and drags that