1

So I'm using Java (processing) and I have an array of objects and I need them to do be able to collide with themselves but I'm not too sure how to do it efficiently. I have a rudimentary way of doing it but it is very poorly written and doesn't allow for a dynamic array.

I currently have a static array but I would like to have a dynamic one in the future. I currently run the method that detects a collision by check for each possible combination. There will always be 3 objects, and it is not possible for there to ever be less than 3.

Here is my code:

Circle[] arrayOfCircles = new Circle[3]; //declare array

void setup() {

  size(1000, 1000);

  for (int i = 0; i < arrayOfCircles.length; i++) {
    createPuck(i);
  } // creates objects

}

void createPuck(int i) {

  float speedY;
  float speedX;

  if (tempSpeedX == 0 && tempSpeedY == 0) {
    speedY = createSpeedY();
    speedY = speedY * multiplier;
    speedX = 3 * multiplier;
  } else {
    speedX = tempSpeedX;
    speedY = tempSpeedY;
    tempSpeedX = 0;
    tempSpeedY = 0;
  }
  arrayOfPucks[i] = new Puck(width, int(random(0, height)), speedX, speedY);
}

int createSpeedY() {

  int tempSpeed = int(random(-3, 3));

  do {
    if (tempSpeed == 0) {
      tempSpeed = int(random(-3, 3));
    }
  } while (tempSpeed == 0);

  return tempSpeed;
}

void draw() {
  detectCollisions();
}

void detectCollisions() {
  for (int i = 0; i < arrayOfCircles.length; i++) {

    boolean collision = false;

    if (i==0) {

      collision = arrayOfCircles[i].detectCollision(arrayOfCircles[i+1]);

      if (collision == true) {
        arrayOfCircles[i].bounce(arrayOfCircles[i+1]);
      }

      collision = arrayOfCircles[i].detectCollision(arrayOfCircles[i+2]);

      if (collision == true) {
        arrayOfCircles[i].bounce(arrayOfCircles[i+2]);
      }
    } else if (i==1) {

      collision = arrayOfCircles[i].detectCollision(arrayOfCircles[i-1]);

      if (collision == true) {
        arrayOfCircles[i].bounce(arrayOfCircles[i-1]);
      }

      collision = arrayOfCircles[i].detectCollision(arrayOfCircles[i+1]);

      if (collision == true) {
        arrayOfCircles[i].bounce(arrayOfCircles[i+1]);
      }
    } else if (i==2) {

      collision = arrayOfCircles[i].detectCollision(arrayOfCircles[i-1]);

      if (collision == true) {
        arrayOfCircles[i].bounce(arrayOfCircles[i-1]);
      }

      collision = arrayOfCircles[i].detectCollision(arrayOfCircles[i-2]);

      if (collision == true) {
        arrayOfCircles[i].bounce(arrayOfCircles[i-2]);
      }
    } // end of if
  } // end of for loop
} // end of function

class Circle {

  float x, y;
  float speedX, speedY;
  final int radius = 10;

  Circle(float x, float y, float speedX, float speedY) {
    this.x = x;
    this.y = y;

    this.speedX = speedX;
    this.speedY = speedY;
  }
  // constructor

  void move() {
    this.x = this.x-speedX; //move left
    this.y = this.y-speedY;
  }

  //methods
  void render() {
    fill(0);
    ellipse(this.x, this.y, this.radius, this.radius);
  }

  void bounce() {
    this.speedX = this.speedX * -1;
    this.speedY = this.speedY * -1;
  }

  boolean detectSelfCollision(Puck other) {
    for (int i = 0; i == 2; i++) {
    }
    float distX = this.x - other.x;
    float distY = this.y - other.y;
    float distance = sqrt( (distX*distX) + (distY*distY) );

    if (distance <= radius*2) {
      return true;
    } else {
      return false;
    }
  }
}

The code does work in that it does what I want but it to but it isn't very neat, there's lots of repetition and isn't very expandable.

Any suggestions or help would be greatly appreciated, I could even recreate any suggestions based upon pseudo-code. I'm just hitting a brick wall here.

  • Could you provide your `Circle` class? – Oleg Cherednik Feb 04 '19 at 19:59
  • If the code works, and you're looking for ways to improve it then [Code Review SE](https://codereview.stackexchange.com) would be a better venue for this question. Be sure to observe their criteria for questions if you do decide to move it there. – John Bollinger Feb 04 '19 at 19:59
  • @oleg.cherednik updated the code section. –  Feb 04 '19 at 20:10
  • @JohnBollinger thank you, I will have a look, the issue is I'm not really sure what I'm looking for. –  Feb 04 '19 at 20:11
  • Well that's the thing, @Jonathan. If you don't know what you're looking for, then how are we supposed to know? Code Review is about general "how do I make it better?" questions. SO is about much more specific questions. – John Bollinger Feb 04 '19 at 20:15

1 Answers1

1

Your detectCollisions() method could be rewritten:

public void detectCollisions() {
    for (int i = 0; i < circles.length; i++)
        for (int j = 0; j < circles.length; j++)
            if (i != j && circles[i].detectCollision(circles[j]))
                circles[i].bounce(circles[j]);
}
Oleg Cherednik
  • 17,377
  • 4
  • 21
  • 35
  • This was exactly what I was looking for, thank you so much! –  Feb 04 '19 at 20:19
  • 1
    @Johnathan Note though that this does not scale well as it is n^2 time. It will be fine for low-ish numbers of circles but will get bad fast as you add more circles. If you plan to have lots of circles then consider looking up more efficient collision detection algorithms, see [something like this](https://stackoverflow.com/questions/2544431/collision-detection-of-huge-number-of-circles) – xtratic Feb 04 '19 at 20:28