Search code examples
javaprocessingcollision-detectioncollision

Rectangle collision - Unwanted overlapping. (Processing IDE)


So I have this simple processing sketch where blocks follow the mouse. It has a basic collision function which detects an intersection between two rectangles then sets rectangle A's position equal to rectangle B's position minus rectangle A's width (assuming rect B is in front of A). Unfortunately this method is insufficient and the rectangles overlap each other slightly. I really want the rectangles to line up perfectly as if they were a strip of rectangles. Is there a way to do this? Here is my runnable sketch below:

class Block {
  color c = color(random(255), random(255), random(255));
  float x = random(width);
  float speed = random(3, 6);
  void run() {
    float dir = mouseX - x;
    dir /= abs(dir);
    x += dir * speed;
    fill(c);
    rect(x, 300, 30, 60);
  }
  void collide() {
    for (Block other : blocks) {
      if (other != this) {
        if (x + 30 > other.x && x + 30 <= other.x + 15)
          x = other.x - 30;
        else if (x < other.x + 30 && x > other.x + 15)
          x = other.x + 30;
      }
    }
  }
}
Block[] blocks = new Block[6];
void setup() {
  size(600, 600);
  for (int i = 0; i < blocks.length; i++)
    blocks[i] = new Block();
}
void draw() {
  background(255);
  for (Block b : blocks) {
    b.run();
    b.collide();
  }
}
void mousePressed() {
  setup();
}

Solution

  • Hi I updated your code following the multi-object collision example found in http://ejohn.org/apps/processing.js/examples/topics/bouncybubbles.html

    The idea is to perform steps in this order:

    1. update the position of each object according to its speed and direction
    2. check for collisions and adapt position to the new constraints
    3. display object

    I created a new method display() for Block that is run after updating the position following a collision detection. The rectangles are not displayed in the run() because they would have an incorrect position. The method overlap() called at setup takes care of overlapping rectangles when initializing the sketch.

    Hope this helps!

    class Block {
      color c = color(random(255), random(255), random(255));
      float x = random(width);
      float speed = random(3, 6);
      void run() {
        float dir = mouseX - x;
        dir /= abs(dir);
        x += dir * speed;
      }
      void display() {
        fill(c);
        rect(x, 300, 30, 60);
      }
      void collide() {
        for (Block other : blocks) {
          if (other != this) {
            if (x + 30 > other.x && x + 30 <= other.x + 15) {
              x = other.x - 30;
            }
            else if (x < other.x + 30 && x > other.x + 15) {
              x = other.x + 30;
            }
          }
        }
      }
      void overlap() {
        for (Block other : blocks) {
          if (other != this) {
            if (x + 30 > other.x && x + 30 <= other.x + 30) {
              x = other.x - 30;
            }
          }
        }
      }
    }
    Block[] blocks = new Block[6];
    void setup() {
      size(600, 600);
      for (int i = 0; i < blocks.length; i++) {
        blocks[i] = new Block();
      }
       for (Block b : blocks) {
         b.overlap();
       }
    }
    void draw() {
      background(255);
      for (Block b : blocks) {
       b.run();
       b.collide();
       b.display();
      }
    }
    void mousePressed() {
      setup();
    }
    

    PS also added some extra curly brackets for 1-line if statements that even though unnecessary make the code more "safe"