Search code examples
arraysoopprocessing

How to combine array data with frameCount in Processing


I am trying to let circled objects appear over time – each independently – and change their positions to randomly chosen new ones after 30 frames. Right now – I only can let them change their position after 30 frames but all together at once… It took me a while to combine them in the way that they change all 30 frames, now I want to untangle them. How is that to achieve? BTW – the "numbers array" at first is giving 6 times the value zero, probably because it is connected to the loop? Is there a way to fix this?

Here you can see the main code:

Circle[] circles = new Circle[6];

color c1 = color(255, 255, 255);
color c2 = color(0, 0, 255);
color c3 = color(255, 255, 255);
color[] colors = { c1, c2, c3 };

int[] numbers = new int[6];

int index;
float rX;
float rY;

void setup () {
  size(540, 960);
  randomizePositions();
  
  index = 5;
  numbers[0] = 5;
  numbers[1] = 10;
  numbers[2] = 15;
  numbers[3] = 20;
  numbers[4] = 25;
  numbers[5] = 30;
}

void randomizePositions() {
  
  for (int i = 0; i <circles.length; i++) {
    rX = random(width);
    rY = random(height);
    index = int(random(numbers.length));
    circles[i] = new Circle(rX, rY, colors[int(random(0, colors.length))], numbers[index]);
  }
}

void draw() {
  background(#c1c1c1);
  for (int i = 0; i < circles.length; i++) {
    circles[i].display();
  }
  if (frameCount % 30 == 0) {
    randomizePositions();
  }
}

and this is the object:

class Circle {

  int size;
  int number;
  float x;
  float y;
  color col;

  Circle(float tempX, float tempY, color tempC, int tempNumber) {
    size = 20;
    x = tempX;
    y = tempY;
    col = tempC;
    number = tempNumber;
  }

  void display() {
    fill(col);
    noStroke();
    ellipse(x, y, size/2.5, size/2.5);
    for (int i = 0; i < number; i++) {
      noFill();
      stroke(col);
      strokeWeight(size/2.5);
      ellipse(x, y, i*size, i*size);
    }
  }
}

Thank you for any kind of help or hint!


Solution

  • You could use the same logic from randomize positions, but outside of a for loop:

    void randomizePosition() {
      int randomCircleIndex = int(random(circles.length));
      int randomColorIndex = int(random(colors.length));
      int randomNumerIndex = int(random(numbers.length));
      rX = random(width);
      rY = random(height);
      circles[randomCircleIndex] = new Circle(rX, rY, colors[randomColorIndex], numbers[randomNumerIndex]);
    }
    

    If you want to avoid creating a new object each time you could move the constructor functionality in a reusable function:

    Circle[] circles = new Circle[6];
    
    color c1 = color(255, 255, 255);
    color c2 = color(0, 0, 255);
    color c3 = color(255, 255, 255);
    color[] colors = { c1, c2, c3 };
    
    int[] numbers = new int[6];
    
    int index;
    float rX;
    float rY;
    
    void setup () {
      size(540, 960);
      randomizePositions();
    
      index = 5;
      numbers[0] = 5;
      numbers[1] = 10;
      numbers[2] = 15;
      numbers[3] = 20;
      numbers[4] = 25;
      numbers[5] = 30;
    }
    
    void randomizePositions() {
    
      for (int i = 0; i <circles.length; i++) {
        rX = random(width);
        rY = random(height);
        index = int(random(numbers.length));
        circles[i] = new Circle(rX, rY, colors[int(random(0, colors.length))], numbers[index]);
      }
    }
    
    void randomizePosition() {
      int randomCircleIndex = int(random(circles.length));
      int randomColorIndex = int(random(colors.length));
      int randomNumerIndex = int(random(numbers.length));
      rX = random(width);
      rY = random(height);
      circles[randomCircleIndex].reset(rX, rY, colors[randomColorIndex], numbers[randomNumerIndex]);
    }
    
    void draw() {
      background(#c1c1c1);
      for (int i = 0; i < circles.length; i++) {
        circles[i].display();
      }
      if (frameCount % 30 == 0) {
        randomizePosition();
      }
    }
    
    class Circle {
    
      int size;
      int number;
      float x;
      float y;
      color col;
      
      Circle(float tempX, float tempY, color tempC, int tempNumber) {
        reset(tempX, tempY, tempC, tempNumber);
      }
      
      void reset(float tempX, float tempY, color tempC, int tempNumber){
        size = 20;
        x = tempX;
        y = tempY;
        col = tempC;
        number = tempNumber;
      }
    
      void display() {
        fill(col);
        noStroke();
        ellipse(x, y, size/2.5, size/2.5);
        for (int i = 0; i < number; i++) {
          noFill();
          stroke(col);
          strokeWeight(size/2.5);
          ellipse(x, y, i*size, i*size);
        }
      }
      
      
    }
    

    Additionally, if you want to reset one circle at time but sequentially (not randomly selecting one from the array) you'd need to use a separate integer to count the currently selected circle index so it can be incremented:

    Circle[] circles = new Circle[6];
    
    color c1 = color(255, 255, 255);
    color c2 = color(0, 0, 255);
    color c3 = color(255, 255, 255);
    color[] colors = { c1, c2, c3 };
    
    int[] numbers = new int[6];
    
    int index;
    float rX;
    float rY;
    
    int currentCircleIndex = 0;
    
    void setup () {
      size(540, 960);
      randomizePositions();
    
      index = 5;
      numbers[0] = 5;
      numbers[1] = 10;
      numbers[2] = 15;
      numbers[3] = 20;
      numbers[4] = 25;
      numbers[5] = 30;
    }
    
    void randomizePositions() {
    
      for (int i = 0; i <circles.length; i++) {
        rX = random(width);
        rY = random(height);
        index = int(random(numbers.length));
        circles[i] = new Circle(rX, rY, colors[int(random(0, colors.length))], numbers[index]);
      }
    }
    
    void randomizePosition() {
      int randomColorIndex = int(random(colors.length));
      int randomNumerIndex = int(random(numbers.length));
      rX = random(width);
      rY = random(height);
      circles[currentCircleIndex].reset(rX, rY, colors[randomColorIndex], numbers[randomNumerIndex]);
      println("reset circle index: " + currentCircleIndex);
      // increment index (and reset after last index using %)
      currentCircleIndex = (currentCircleIndex + 1) % circles.length;
    }
    
    void draw() {
      background(#c1c1c1);
      for (int i = 0; i < circles.length; i++) {
        circles[i].display();
      }
      if (frameCount % 30 == 0) {
        randomizePosition();
      }
    }
    
    class Circle {
    
      int size;
      int number;
      float x;
      float y;
      color col;
      
      Circle(float tempX, float tempY, color tempC, int tempNumber) {
        reset(tempX, tempY, tempC, tempNumber);
      }
      
      void reset(float tempX, float tempY, color tempC, int tempNumber){
        size = 20;
        x = tempX;
        y = tempY;
        col = tempC;
        number = tempNumber;
      }
    
      void display() {
        fill(col);
        noStroke();
        ellipse(x, y, size/2.5, size/2.5);
        for (int i = 0; i < number; i++) {
          noFill();
          stroke(col);
          strokeWeight(size/2.5);
          ellipse(x, y, i*size, i*size);
        }
      }
      
      
    }