Stop spawning near each other! - mouse input issues with ellipse

Hello! I have a program that creates a new object that displays an ellipse whenever I click the mouse. I want a new object to be created only if I click outside of an existing ellipse. However currently it creates a new object no matter where I click and I don’t understand why. I’d appreciate your help. :slight_smile:

void mouseReleased(){
  
  if(things.isEmpty()){
   things.add(new Thing(mouseX,mouseY));
  }
  
//go through ArrayList of things
  for (Thing t: things){
    if(dist(mouseX,mouseY,t.x,t.y)>20){
    things.add(new Thing(mouseX,mouseY));
    break;
     }
  }

I can post my full code if that helps, too.

Thanks!

1 Like

This is what your code says:

Look at each Thing.
  If the Thing we're looking at is not close to where we clicked,
    add a new Thing.

So a new Thing is added UNLESS you are close to EVERY Thing. Whoops!

What you want is code that says this:

Assume we will add our new Thing.
Look at every Thing.
  If the thing is close to where we clicked,
    remember we won't be adding our new Thing.
If we still think it's okay to add the new Thing,
  Add it.
2 Likes

Thanks! I’m not sure if this is exactly the solution you suggested but your answer led me to try adding booleans, and it seems to work. :slight_smile:

 for (Thing t: things){
      if(dist(mouseX,mouseY,t.x,t.y)<20){
       addNew=false;  
       break;
      }else{
        addNew=true;
      }
    }
    
    if(addNew){
      things.add(new Thing(mouseX,mouseY));}

One quick suggestions to clean up:

  1. you are testing for “is colliding”, rather than “not not add-ing” – make your boolean false by default, name it what the check does, and don’t define it over and over again as the opposite value if the check fails – just leave it false.
boolean collide = false;
for (Thing t: things){
  if(dist(mouseX,mouseY,t.x,t.y) < 20){
    collide = true;
    break;
  }
}
if(!collide){
  things.add(new Thing(mouseX,mouseY));
}

Notice that now you could take this and add it to your Thing class as a class method:

boolean isColliding(int x, int y){
  boolean collide = false;
  for (Thing t: things){
    if(dist(x, y, t.x, t.y) < 20){
      collide = true;
      break;
    }
  }
  return collide;
}

…and call it statically in your Thing class when you click to add:

if(Thing.collide(mouseX, mouseY)){
  things.add(new Thing(mouseX, mouseY));
}

This is neat because you are now checking if there is a Thing-shaped hole were you clicked. If you Thing is a triangle. or a square, or a circle, the same logic that Thing 1 and Thing 2 would use to bounce off each other can also be used to check if a hole can be filled by a new Thing.

1 Like