Trying to call a function from one class to another. Worked until I made created an array of the Class

Hi,
I’ve probably not described the problem in the title properly. The error I get is
‘sx cannot be resolved or is not a field’
Me again. I’m adapting an old sketch just as a practice tool to help cement the various concpets of using sine fucntions, classes, and arrays, in my head. The code I have works until I place the Flower class in an array and try to call flower.sx in the Petal array class. It’s a bit clear if I post the code.

Flower [] flower = new Flower[10]; 
Petal [] petal = new Petal[10];
void setup(){
 size(400,400);
   for(int i = 0; i <flower.length; i++){
      for(int j = 0; j < petal.length; j++){
     flower[i] = new Flower();  
     petal[j] = new Petal();
       }
    }
  
}

void draw(){
  background(85,135,200);
    for(int i = 0; i < flower.length; i++){
     flower[i].stem(); 
    }
   for(int  i = 0; i < petal.length; i++){
    petal[i].oscillate();
    petal[i].display();
   }
}

//----classes ----
class Flower{
     //location -stem
    float sx;
    float sy;
     //size- stem
     float st;
     float slen;
     color sc;
    
  Flower(){
   //location shape colour
   sx = random(40, width -40);
   sy = random(100, height- 100);
   st = 3;
   slen = 60;
   sc = color (10, 255, 85);
   
  }
    
    void stem(){
      strokeWeight(st);
      stroke(sc);
     line(sx, sy,sx, sy +slen);  
    }
}
//---petal class---
class Petal{
  float xtheta;
  float ytheta;
  
  float dxtheta;
  float dytheta;
    
    Petal(){
      xtheta = 0;
      ytheta = 0;
      //increment values
      dxtheta = random(-0.03,0.03);
      dytheta = random(-0.03,0.03);
    }

    void oscillate()  {
        // Increment angles   
        xtheta += dxtheta;
        ytheta += dytheta;
    }   

    void display()  {   
        // Map results of sine / cosine to length of petal
        float x = map(sin(xtheta), -1,1, -30,30);   
        float y = map(cos(ytheta), -1,1, -30,30);
        stroke(10,255,85);  
        strokeWeight(2);

        // draw circle and line
//the flower.sx worked until tried to make an array of the flower class.
        line(width/2, height/2, flower.sx +x,flower.sy +y); //flower.sx doesn't work!! 
        fill(200,85,10, 150);
        noStroke();
        ellipse(flower.sx +x,flower.sy +y,20,20);  
    }

}//clss

Again, it’s probably some basic syntax I’m not understanding. I’ve had a look at soe tutorials but nothing covers this specific case - that I’ve found. Again calling flower.sx worked until I created an array of the Flower class.

Thanks again for any help!

1 Like

I have sorted it out by creating a global value and then having the flower.sx value equal it. The code now works , but runs faster than I’d like it too. I can sort out the speed by playing with the values manually, but does any one know why the oscillation of my petals speeds up? EDIT : I have found if I change the flower[n] the sketch speeds up or slows down the higher or lower the number respectively.
EDIT 2: I put in a frameRate variable( this doesn’t stop the flower[n] fromeffecting the speedof the oscillation in setup to control the speed. Is there another way to do this?
Also all my flowers have the same random petals, how would I change that?
re-edited code below.

 //if i increase flower[n] the 'floating' speeds up. Not sure why..
Flower []  flower = new Flower[10];
Petal [] petal = new Petal[10];

//global value to call for loaction of petals and stem
float tempx; 
float tempy;

void setup(){
 size(600,600);
  for(int i =0; i <flower.length; i++){
     for(int j = 0; j < petal.length; j++){
    flower[i] = new Flower();
       petal[j] = new Petal();
     }
  }
    }

void draw(){
  background(85,135,250);
    for(int i = 0; i < flower.length; i++){
      for(int  j = 0; j < petal.length; j++){
    flower[i].stem(); 
     tempx = flower[i].sx;
     tempy = flower[i].sy;
        //petal
        petal[j].oscillate();
        petal[j].display();
       }
    }
}

//--classes----
class Flower{
     //location -stem
    float sx;
    float sy;
     //size- stem
     float st;
     float slen;
     color sc;
    
  Flower(){
   //location shape colour
   sx = random(30, width-30);
   sy = random(100, height-100);
   st = 3;
   slen = 60;
   sc = color (10, 255, 85);
   
  }
    
    void stem(){
      strokeWeight(st);
      stroke(sc);
     line(sx, sy,sx, sy +slen);  
     }  
}
//---petal class--

class Petal{
  float xtheta;
  float ytheta;
  
  float dxtheta;
  float dytheta;
    
    Petal(){
      xtheta = 0;
      ytheta = 0;
      //incerement random
      dxtheta = random(-0.03,0.03);
      dytheta = random(-0.03,0.03);
    }

    void oscillate()  {
        // Increment angles   
        xtheta += dxtheta;
        ytheta += dytheta;
    }   

    void display()  {   
        // Map results of sine / cosine to width and height of window
        float x = map(sin(xtheta), -1,1, -20,20);   
        float y = map(cos(ytheta), -1,1, -20,20);
        stroke(10,255,85,100);
        strokeWeight(2);
        
        // draw circle and line 
        //now uses the global values as a location
        line(tempx,tempy,tempx +x,tempy +y); 
        
        fill(200,85,10, 150);
        noStroke();
        ellipse(tempx +x, tempy +y, 20,20);  
    }
}
1 Like

Ah, what a great problem.

When you had one flower, it had 10 petals.

In a sense, the petals were a part of the flower.

But the structure of your code does not reflect this - you have 10 petals that are global, and each flower shares them.

What you should do is put the array of 10 petals INSIDE the flower class. This way, each flower object has its own set of 10 petals. When you draw a flower, it can also deal with drawing its own petals.


For timing, use the millis() function. You can record a number that will be the next time things should update, and check to see if the current value of millis() is more than tha. If it is, you can record a new time to update (millis() + 5000, say), and then do yur update.

4 Likes

Cheers for the help I’ll try it out later today (or when I get the chance :slight_smile: ) )
Thanks again!!!

As TfGuy says…

Flower f;
//---------------------------------------- setup
void setup () {
  f = new Flower ();
}
//---------------------------------------- draw
void draw () {
}
//---------------------------------------- Flower class
class Flower {
  int numPetals;
  Petal [] p;
  //-------------------------------------- constructor
  Flower () {
    println ("i am a flower");
    numPetals = 10;
    p = new Petal [numPetals];
    for (int i=0; i<numPetals; i++) {
      p[i] = new Petal();
    }
  }
  //--------------------------------------
}
//---------------------------------------- end of class


//---------------------------------------- Petal class
class Petal {
  int numPetals;
  //-------------------------------------- constructor
  Petal () {
    println ("i am a petal");
  }
  //--------------------------------------
}
//---------------------------------------- end of class

now you can address the petals with a method in the flower-object.
or you can do:
f.p[0].method(); or f.p[0].field;

Bildschirmfoto 2020-08-27 um 23.05.24