Problem with translate() in class when using arraylist

Hi, I really need help with this code. I’ve been trying to make infinite jellyfish appear from the bottom of the screen and move upwards until they disappear. For some reason after a while the jellyfish start appearing from the middle of the screen even though I set the translation to more than 800 and only 4 of them appear. I’m thinking that more are being added too far up the screen so they’re not visible. Below is the code:


float xSpeed;
float ySpeed;
float ellipseX = 500;
float ellipseY = 550;
ArrayList<Jellyfish> jellies = new ArrayList<Jellyfish>();
ArrayList<Jellyfish> visibleJellies = new ArrayList<Jellyfish>();
float ty = 500;
int time=0;
int counter;

void setup(){
 counter=0;

for(int i =0; i<100; i++){
  jellies.add(new Jellyfish(random(0, 1500), 850, random(-40, 40), random(0.05, 0.35)));
}
 size(1500, 850);

void draw() {
  background(8, 22, 46);
  for (int s = 0; s < stars.length; s++) {    
    stars[s].display();
  }
  image(b, 0, 0);
  if (millis()>time+2000) {
    time=millis();
    visibleJellies.add(jellies.get(counter));
    if (counter < 100) counter++;
    else counter = 0;
  }

  for (int i = 0; i < visibleJellies.size(); i++) {
    visibleJellies.get(i).display();
  }
}



class Jellyfish{
  float transX;
  float transY;
  float r;
  float s;


  
Jellyfish(float transX, float transY, float r, float s){
this.transX = transX;
this.transY = transY;
this.r = r;
this.s = s;

}

void display(){
  pushMatrix();
  translate(transX, transY);
  rotate(radians(r));
  scale(s);
  strokeWeight(5);
  fill(5, 29, 242, 40);
  stroke(5, 29, 242);
  xSpeed += 0; 
  ySpeed -= random(5, 6);

 
  
  beginShape();
  strokeWeight(12);
  
  arc(500+xSpeed, 500+ySpeed, 500, 500, -PI, 0);
  endShape();
  //tentacle1
  beginShape();
  
  
  noFill();
  curveVertex(500+xSpeed, ty+ySpeed); 
  curveVertex(500+xSpeed, ty+ySpeed); 
  curveVertex(600+xSpeed, ty+250+ySpeed);
  curveVertex(550+xSpeed, ty+350+ySpeed);
  curveVertex(475+xSpeed, ty+400+ySpeed); 
  endShape();
  
  //tentacle2
  beginShape();
 
  
  noFill();
  curveVertex(375+xSpeed, ty+ySpeed); 
  curveVertex(375+xSpeed, ty+ySpeed); 
  curveVertex(325+xSpeed, ty+100+ySpeed);
  curveVertex(350+xSpeed, ty+325+ySpeed);
  curveVertex(250+xSpeed, ty+350+ySpeed); 
  endShape();
  
  //tentacle3
  beginShape();
  
  
  noFill();
  curveVertex(650+xSpeed, ty+ySpeed); 
  curveVertex(650+xSpeed, ty+ySpeed); 
  curveVertex(650+xSpeed, ty+100+ySpeed);
  curveVertex(700+xSpeed, ty+325+ySpeed);
  curveVertex(550+xSpeed, ty+350+ySpeed); 
  endShape();
  

  popMatrix();
}
}


1 Like

Hi! First of all, nice drawing! I want to point out that the code you pasted has some errors (setup isn’t closed, there are some missing variables like stars and b… which I assume are not relevant to your question).

I think you are almost there, but since ySpeed is declared globally and not for each jellyfish, the position is applied to all the jellyfish.

Some other suggestions:

  • instead of using xSpeed and ySpeed in each draw (arc/vertex/etc), you can skip these values and instead use it once in translate just before the first beginShape, which will make the code more concise.
  • rather a small point but what you mean by xSpeed and ySpeed is not speed but in fact, position…
  • what happens after 100 jellyfish appear? Actually, it will give an error here:
    if (counter < 100) counter++;
    else counter = 0;

because this permits counter to be 100. What you want instead is

    counter++;
    if (counter >= jellies.size()) counter = 0;

but still the code won’t work as you expect because old jellyfish won’t be initialized (they are already outside the top edge, and you want to give life to this jellyfish again). There are a few ways to fix this so that the new jellyfish will appear at the bottom. One is to naively instantiate a new jellyfish object instead of moving from jellies to visibleJellies. Another (a bit more efficient) way would be to add an init function to reset the position of the “old” jellyfish - but in this case, you should not visibleJellies.add again because the same object will be added in the ArrayList over and over and end up in a weird situation (try millis()>time+2 so you don’t have to wait for 3 minutes for debugging) …

2 Likes

One of errors size is not at first setup

void setup(){
 size(1500, 850);
 counter=0;

for(int i =0; i<100; i++){
  jellies.add(new Jellyfish(random(0, 1500), 850, random(-40, 40), random(0.05, 0.35)));
}
 
}

And take in consideration Random return Float

1 Like

Hello, many thanks for this detailed answer. Yes my problem is that I am trying to instantiate a new jellyfish object so that new ones appear from the bottom of the screen but for some reason by the 3rd one they start appearing in the middle of the screen and I have no idea how to solve it. I want new ones to appear from the bottom of the screen every x seconds. Thanks

?
I understood your question and answered in the post above :slight_smile:

yes I’ve already tried adding new jellyfish but the jellyfish still start appearing from the middle of the screen after the 2nd/3rd one…that’s why I attempted to use the visiblejellies but still didn’t work.

micuat pointed out a few mistakes of yours

Did you correct them all?

If you have please post your entire code again otherwise read his post again and keep on working on your Sketch

here’s the answer - in case you missed it

1 Like

I must have been doing something wrong (sorry I’m only a beginner). Many thanks for your help, I managed to make it work eventually :slight_smile: