Questions about BouncyBubbles example

Just to be sure. The part below is called a constructor, right?

  Ball(float xin, float yin, float din, int idin, Ball[] oin) {
    x = xin;
    y = yin;
    diameter = din;
    id = idin;
    others = oin;
  }

Okay, so sorry about earlier but I made a mistake. I forgot that when you assign an array like this you are not creating a real copy of the object so the behavior is a bit different.

When you do this: others = oin you are not create a copy of oin (wich is you balls array). What you are doing is giving another name to your balls array, another way to access it.

This way, no matter the changes that you do on balls you will also have it on others since it is actually the same thing but just called differently, a bit like a nickname.

Try out the simplify code bellow to understand it.

final int numBalls = 10;
Ball[] balls = new Ball[numBalls];

void setup() {
  // Create the balls
  for (int i = 0; i < numBalls; i++) {
    balls[i] = new Ball("Ball_" + i, balls);
  }

  // Describe the balls
  for (int i = 0; i < numBalls; i++) {
    balls[i].describeItself();
  }
}

class Ball {
  private String name;
  private Ball[] others;

  // Constructor
  Ball(String name, Ball[] oin) {
    this.name = name;
    this.others = oin;
  }

  // Description of the ball - list all the elements of others
  void describeItself() {
    println("Name: " + name);
    printArray(others);
    //for (int i = 0; i < others.length; i++) {
    //  println("[" + i + "]" + " " + others[i].getName());
    //}
    println("");
  }
  
  // Return the name of the ball
  String getName() {
    return name;
  }
}

So in the end, all the ball that you have created will have a way to interact with all the other balls that you have created. Another way to do it would be to first create all your balls and then update your others array. The following code does exactly the same but is easier to understand:

final int numBalls = 10;
Ball[] balls = new Ball[numBalls];

void setup() {
  // First you create all the balls
  for (int i = 0; i < numBalls; i++) {
    balls[i] = new Ball("Ball_" + i);
  }

  // Then you update the others array of all your balls
  for (int i = 0; i < numBalls; i++) {
    balls[i].updateOthers(balls);
  }
  
  // Describe the balls
  for (int i = 0; i < numBalls; i++) {
    balls[i].describeItself();
  }
}

class Ball {
  private String name;
  private Ball[] others;

  // Constructor
  Ball(String name) {
    this.name = name;
  }

  void updateOthers(Ball[] oin) {
    others = oin;
  }
  
  // Description of the ball - list all the elements of others
  void describeItself() {
    println("Name: " + name);
    printArray(others);
    //for (int i = 0; i < others.length; i++) {
    //  println("[" + i + "]" + " " + others[i].getName());
    //}
    println("");
  }
  
  // Return the name of the ball
  String getName() {
    return name;
  }
}

OK. Two consequent questions:

  1. It this possibility of having two ways to access the same thing specific to Java or does it exist in other languages?
  2. Doesn’t this way of coding spoil memory as each ball has an unuseful reference to itself within the “others” array?
  1. It is not specific to java. You can read about references and pointers.
  2. Since you are just referring to something and not creating another copy of it you are not spoiling memories.
1 Like

If by that you mean having extra alias variables for the same object, worry not. :angel:
Each reference variable in Java just uses up 4 bytes (8 bytes in rare cases). It’s pretty insignificant. :tipping_hand_man:

Not exactly balls bouncing off each other, but merely a sketch where a line() is drawn linking them: :volleyball:
Studio.ProcessingTogether.com/sp/pad/export/ro.989GaZC5t7EkE

Notice though on the sketch above, the Bubble class doesn’t access the global field balls[]. :raised_hand:
The whole job is done within draw(), which is solely responsible to iterate over the array balls[]. :nerd_face: