1

Recently I have been working on a game with an Arduino using Java in Processing and for this problem I have cut out all unnecessary Arduino code to show only the code I am having issues with which is straightly Java related in Processing.

Goal: So my goal right now is to have a collision detection going between some randomly falling ellipses and a bouncing rectangle back and forth on the bottom of screen. The idea is to just have when the objects collide to do something real simple like turn the background color red.

Issues: So there are two issues I am currently facing. One is I know how to make a moving object collide with a static object however I am having difficulty with two moving objects and any examples are usually rectangle on rectangle or ellipse ellipse which isn't helpful because a ellipse hitting a rectangle is much different from two of the same forms hitting each other.

Second issue I know I have to use a boolean however since the ellipses are at random coordinates and such I am using float not an int and booleans don't function with floats.

Last quick issue is if I need the x and y for the boolean not only are they floats but they are placed in a class which makes them unreachable (see code below). I could duplicate the same floats and place them where the initial ints are defined except I have no clue how bad doing something like that is.

int direction1 = 100;
int speedX = 12;
int heightWidth=40;
int bounceSize= 40;
int ellipseSizeone=40;
int ellipseSizetwo=50;
float x = random(800);
float y = random(-500);

Meteor meteors;
int total = 10;
Meteor[] fall = new Meteor[total]; 

void setup() {
    size (800, 500);
    background(0);
    smooth();
    noStroke();

    for (int i = 0; i < fall.length; i++) {

        fall[i] = new Meteor(); 
        meteors = new Meteor();
    }
}

void draw() {
   background(0);

   direction1+=speedX;
   if (direction1 > width-bounceSize) {
       direction1 = width-bounceSize;
       speedX = -12;
   }
   if (direction1 < 0) {
       direction1 = 0;
       speedX = 12;
   }
   rect(direction1, 450, heightWidth, heightWidth);
   fill(0,20);
   rect(0,0,800,500);

   for (int i = 0; i < fall.length; i+=3) {
       fall[i].fall();
   }
   fill(0,255,0);
}

class Meteor {
    float x = random(800);
    float y = random(-500);

    void fall() {
        y = y + 3;
        fill(random(200),0,0);
        ellipse(x, y, ellipseSizeone, ellipseSizetwo);

        if(y>height){
            x = random(800);
            y = 0;
        }
    }
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • This question has also been crossposted [here](https://discourse.processing.org/t/having-multiple-moving-objects-collide-detection-issues/3463). – Kevin Workman Sep 13 '18 at 17:27

1 Answers1

0

I recommend to reduce the issue to a simple axis aligned bounded box intersection test. I is sufficient to approximate the ellipse by a box, to do the intersection test. Note, an accurate intersection test of an ellipse and a rectangle can be applied later.

Add an intersection test method to the class Meteor:

class Meteor {

    // .....

    boolean intersect(float rx, float ry, float rw, float rh) {
        return  
            (x + ellipseSizeone/2.0f) > rx &&
            (rx + rw) > (x - ellipseSizeone/2.0f) &&
            (y + ellipseSizetwo/2.0f) > ry &&
            (ry + rh) > (y - ellipseSizetwo/2.0f);
    }
}

Use a variable of type boolean, to notify the intersection and. Check each object if it intersects the rectangle, in a loop and. The results of the intersection test have to be concatenated by a logical or operation (||). If one object intersect the rectangle, then the test can be aborted:

void draw() {

    boolean hit = false;
    for (int i = 0; hit == false && i < fall.length; i+=3) {
        hit = hit || fall[i].intersect(direction1, 450, heightWidth, heightWidth);
    }

    if ( hit )
        background(255, 0, 0);
    else
        background(0); 

    // .....

}

Note, for an accurate result the y position of the falling object should be incremented, after the objects have been drawn, because the intersection test tests the current position and not the next position.
And of course, draw the rectangle, before its position is updated for the next frame.

Full draw function:

void draw() {

    boolean hit = false;
    for (int i = 0; hit == false && i < fall.length; i+=3) {
        hit = hit || fall[i].intersect(direction1, 450, heightWidth, heightWidth);
    }

    if ( hit )
        background(255, 0, 0);
    else
        background(0); 

    rect(direction1, 450, heightWidth, heightWidth);
    fill(0,20);
    rect(0,0,800,500);

    direction1+=speedX;
    if (direction1 > width-bounceSize) {
        direction1 = width-bounceSize;
        speedX = -12;
    }
    if (direction1 < 0) {
        direction1 = 0;
        speedX = 12;
    }

    for (int i = 0; i < fall.length; i+=3) {
        fall[i].fall();
    }
    fill(0,255,0);
}

Full class Meteor:

class Meteor {
    float x = random(800);
    float y = random(-500);

    void fall() {
        fill(random(200),0,0);
        ellipse(x, y, ellipseSizeone, ellipseSizetwo);

        y = y + 3; 
        if(y>height){
            x = random(800);
            y = 0;
        }
    }

    boolean intersect(float rx, float ry, float rw, float rh) {
        return  
            (x + ellipseSizeone/2.0f) > rx &&
            (rx + rw) > (x - ellipseSizeone/2.0f) &&
            (y + ellipseSizetwo/2.0f) > ry &&
            (ry + rh) > (y - ellipseSizetwo/2.0f);
    }
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Thank you so much also a quick question the f after 2.0 is to set it to a float value correct? –  Sep 12 '18 at 22:28
  • @Azaels Yes it is. A `double`will be automatically cast to `float`. See [Convert double to float in Java](https://stackoverflow.com/questions/32837783/convert-double-to-float-in-java). – Rabbid76 Sep 13 '18 at 04:56