PVector constructor, Recursive class

I'm trying to figure out how to set a PVector as an arguement for my Spawnball class, but "Spawnball(int d, PVector loc)" gives an error. Also I'd like to add a spawn function that draws multiple ellipses on top of the original ball. I'd like to do this in a way that calls the class within itself, but I have no idea how to structure the code for that. Thanks!

Spawnball sb = new Spawnball(50);
Spawnball sb2 = new Spawnball(30);
void setup() {
  size(850, 650);
  noCursor();
}

void draw() {
  background(0);
  sb.update();
  sb.display();
  noFill();
  stroke(200);
  ellipse(mouseX, mouseY, 8, 8);
}

class Spawnball {
  int dia;
  PVector loc;
  PVector vel;
  PVector acc;

  Spawnball(int d) {
    dia = d;
    loc = new PVector(0, 0);
    vel = new PVector(0, 0);
    acc = new PVector(0, 0);
  }

  void update() {
    PVector pos = new PVector(mouseX, mouseY);
    pos.sub(loc);
    pos.setMag(.1);
    acc = pos;
    vel.add(acc);
    loc.add(vel);
    acc.mult(0);
    vel.limit(3);
  }

  void display() {
    fill(10, 175, 3*dia);
    noStroke();
    ellipse(loc.x, loc.y, dia, dia);
  }
}

Answers

  • I'm trying to figure out how to set a PVector as an arguement for my Spawnball class, but "Spawnball(int d, PVector loc)" gives an error.

    Can you post the code that gives an error?

    I'd like to do this in a way that calls the class within itself, but I have no idea how to structure the code for that.

    This may help you:

  • Spawnball sb = new Spawnball(50, (0, 0));
    
    void setup() {
      size(850, 650);
      noCursor();
    }
    
    void draw() {
      background(0);
      sb.update();
      sb.display();
    
      noFill();
      stroke(200);
      ellipse(mouseX, mouseY, 8, 8);
    }
    
    class Spawnball {
      int dia;
      PVector loc = new PVector(0, 0);
      PVector vel;
      PVector acc;
    
      Spawnball(int d, PVector l) {
        dia = d;
        l = loc;
        vel = new PVector(0, 0);
        acc = new PVector(0, 0);
      }
    
      void update() {
        PVector pos = new PVector(mouseX, mouseY);
        pos.sub(loc);
        pos.setMag(.1);
        acc = pos;
        vel.add(acc);
        loc.add(vel);
        acc.mult(0);
        vel.limit(3);
      }
    
      void display() {
        fill(10, 4*dia, 3*dia);
        noStroke();
        ellipse(loc.x, loc.y, dia, dia);
      }
    }
    
  • both of the examples that you shared create recursions through functions, I'd like to call an instance of my class within the class itself. Is that not possible?

  • If I create the ball as a function, it doesn't animate. Is there a way I can fix that?

    void setup() { size(850, 650); noCursor(); }

    void draw() {
      background(0);
      Spawnball(50);
    
      noFill();
      stroke(200);
      ellipse(mouseX, mouseY, 8, 8);
    }
    
    void Spawnball(int dia) {
      PVector loc = new PVector(0, 0);
      PVector vel;
      PVector acc;
    
      vel = new PVector(0, 0);
      acc = new PVector(0, 0);
    
      PVector pos = new PVector(mouseX, mouseY);
      pos.sub(loc);
      pos.setMag(.1);
      acc = pos;
      vel.add(acc);
      loc.add(vel);
      acc.mult(0);
      vel.limit(3);
    
      fill(10, 4*dia, 3*dia);
      noStroke();
      ellipse(loc.x, loc.y, dia, dia);
    }
    
  • edited March 2016

    I'm trying to figure out how to set a PVector as an arguement for my Spawnball class, but "Spawnball(int d, PVector loc)" gives an error.

    Spawnball sb = new Spawnball(50, new PVector(0, 0));
    

    both of the examples that you shared create recursions through functions, I'd like to call an instance of my class within the class itself. Is that not possible?

    I don't know, but I've tried to create a Spawnball object inside of the Spawnball class and the skecth didn't run so I don't think so.

    But what exactly do you want to do? Isn't it possible to do with only the method that displays the ball being recursive? Or a recursive function outside of the class used to create Spawnball objects? Or maybe creating another class that contains some Spawnball objects, like a particle system?

  • edited March 2016

    Ok so I tried creating a separate class "subSpawn" calls the spawnball class but when I run the sketch the balls don't move. I also tried just generating a bunch of balls within the spawnball class with a for loop, but only one of the objects reacts properly to the mouse

    second class: int diameter;

    Subspawn sbS1 = new Subspawn(50);
    void setup() {
      size(850, 650);
      noCursor();
      textAlign(CENTER);
    }
    
    void draw() {  
      background(0);
    
      sbS1.spawn();
    }
    
    class Spawnball {
      int dia;
      PVector loc = new PVector(0, 0);
      PVector vel;
      PVector acc;
    
      Spawnball(int d, PVector l) {
        dia = d;
        loc = l;
        vel = new PVector(0, 0);
        acc = new PVector(0, 0);
      }
    
      void keyPressed() {
        if (key == ' ') {
          sketchStart = true;
        }
        if (sketchStart == true) {
          PVector pos = new PVector(mouseX, mouseY);
          pos.sub(loc);
          pos.setMag(.1);
          acc = pos;
          vel.add(acc);
          loc.add(vel);
          acc.mult(0);
          vel.limit(3);
        } else {
          fill(255);
          textSize(25);
          text("Press SPACE to start", width/2, 45);
        }
        noFill();
        stroke(200);
        ellipse(mouseX, mouseY, 8, 8);
      }
    
      void display() {
        fill(10, 4*dia, 3*dia);
        noStroke();
        ellipse(loc.x, loc.y, dia, dia);
      }
    }
    
    class Subspawn {
      int dia;
      Subspawn(int d) {
        dia = d;
      }
      void spawn() {
        for (int i = 300; i < 500; i = i+50) {
          Spawnball sb = new Spawnball(dia, new PVector(i, i));
          sb.display();
          sb.keyPressed();
        }
      }
    }
    

    for loop:

        boolean sketchStart = false;
    
        Spawnball sb = new Spawnball(50, 5, new PVector(100, 100));
    
        void setup() {
          size(850, 650);
          noCursor();
          textAlign(CENTER);
        }
    
        void draw() {  
          background(0);
          sb.display();
          sb.keyPressed();
        }
    
        class Spawnball {
          int dia;
          int num;
          PVector loc = new PVector(0, 0);
          PVector vel;
          PVector acc;
    
          Spawnball(int d, int n, PVector l) {
            num = n;
            dia = d;
            loc = l;
            vel = new PVector(0, 0);
            acc = new PVector(0, 0);
          }
    
          void update() {
            PVector pos = new PVector(mouseX, mouseY);
            pos.sub(loc);
            pos.setMag(.1);
            acc = pos;
            vel.add(acc);
            loc.add(vel);
            acc.mult(0);
            vel.limit(3);
          }
    
          void display() {
            fill(10, 4*dia, 3*dia);
            noStroke();
            for (int i=1; i<num; i+=1) {
            ellipse(i*loc.x, i*loc.y, dia, dia);
            }
          }
          void keyPressed() {
            if (key == ' ') {
              sketchStart = true;
            }
            if (sketchStart == true) {
              sb.update();
            } else {
              fill(255);
              textSize(25);
              text("Press SPACE to start", width/2, 45);
            }
            noFill();
            stroke(200);
            ellipse(mouseX, mouseY, 8, 8);
          }
        }
    
  • edited March 2016

    Ok so I tried creating a separate class "subSpawn" calls the spawnball class but when I run the sketch the balls don't move.

    The balls don't move because each time you call sbS1.spawn() you're recreating them at their initial position.

    boolean sketchStart;
    Subspawn sbS1;
    
    void setup() {
      size(850, 650);
      noCursor();
      textAlign(CENTER);  
      sbS1 = new Subspawn(50);
    }
    
    void draw() {  
      background(0);   
      sbS1.spawn();
    }
    
    void keyPressed() {
      if (key == ' ') {
        sketchStart = true;
      }
    }
    
    class Spawnball {
      int dia;
      PVector loc;
      PVector vel;
      PVector acc;
    
      Spawnball(int d, PVector l) {
        dia = d;
        loc = l;
        vel = new PVector(0, 0);
        acc = new PVector(0, 0);
      }
    
      void move() {    
        if (sketchStart == true) {
          PVector pos = new PVector(mouseX, mouseY);
          pos.sub(loc);
          pos.setMag(.1);
          acc = pos;
          vel.add(acc);
          loc.add(vel);
          acc.mult(0);
          vel.limit(3);
        }   
      }
    
      void display() {
        fill(10, 4*dia, 3*dia);
        noStroke();
        ellipse(loc.x, loc.y, dia, dia);
      }
    }
    
    class Subspawn {
      int dia;
      Spawnball[] sb;
    
      Subspawn(int d) {
        dia = d;
        sb = new Spawnball[4];
        for (int i = 0; i < 4; i++) {
          sb[i] = new Spawnball(dia, new PVector(300 + 50*i, 300 + 50*i)); 
        }    
      }
    
      void spawn() {
        if (!sketchStart) {
          fill(255);
          textSize(25);
          text("Press SPACE to start", width/2, 45);
        }
    
        noFill();
        stroke(200);
        ellipse(mouseX, mouseY, 8, 8);
    
        for (int i = 0; i < sb.length; i++) {           
          sb[i].move();
          sb[i].display();
        }
      }
    }
    
  • There is no such thing as a 'recursive' class, but it is possible for class to have fields/attributes of the same type, this is commonly used to create tree data structures. This is not necessary in this case.

    I have created an example sketch based on your code which I believe does what you want. Adapt it in any way you wish.

    // Use an ArrayList rather than an array because the 
    // number of balls will increase as we spawn more
    ArrayList<Spawnball> balls = new ArrayList<Spawnball>();
    // Number of balls to Spawn when the 's' key is typed
    int nbrToSpawn = 6;
    
    void setup() {
      size(850, 650);
      noCursor();
      // Add a SSpawnball in a random position on the screen
      balls.add(new Spawnball(60, random(width), random(height)));
    }
    
    void draw() {
      background(0);
      // Update and draw all the Spawnballs
      for (Spawnball sb : balls) {
        sb.update();
        sb.display();
      }
      noFill();
      stroke(200);
      ellipse(mouseX, mouseY, 8, 8);
    }
    
    void keyTyped() {
      if (key == 's') {
        // Pick an existing Spawnball at random
        int n = int(random(balls.size()));
        Spawnball sb = balls.get(n);
        // Spawn balls arround the chosen Spawnball
        float ang = TWO_PI/nbrToSpawn;
        for (int i = 0; i < nbrToSpawn; i++) {
          float dx = sb.dia * cos(i * ang);
          float dy = sb.dia * sin(i * ang);
          Spawnball sbnew = new Spawnball(sb, dx, dy);
          balls.add(sbnew);
        }
      }
    }
    
    class Spawnball {
      int dia;
      PVector loc;
      PVector vel;
      PVector acc;
    
      Spawnball(int d, float px, float py) {
        dia = d;
        loc = new PVector(px, py);
        vel = new PVector(0, 0);
        acc = new PVector(0, 0);
      }
    
      // This constructor is used when spawing balls
      Spawnball(Spawnball sb, float deltaX, float deltaY) {
        dia = round(max(5, sb.dia * 0.6));
        loc = new PVector(sb.loc.x + deltaX, sb.loc.y + deltaY);
        vel = new PVector(0, 0);
        acc = new PVector(0, 0);
      }
    
      void update() {
        acc.set(mouseX - loc.x, mouseY - loc.y);
        acc.setMag(0.05);
        vel.add(acc);
        loc.add(vel);
        acc.mult(0);
        // Limit the velocity so the smaller balls travel faster
        vel.limit(10000/(dia * dia));
      }
    
      void display() {
        fill(10, 175, 3*dia);
        stroke(0);
        ellipse(loc.x, loc.y, dia, dia);
      }
    }
    
Sign In or Register to comment.