0

Can someone help me, I can't seem to get my collision detection between an array of balls and a rectangle object to work.

var balls = [];
var obstacle;

function setup() {
  createCanvas(windowWidth, windowHeight);
  obstacle = new Obstacle();
}

function draw() {
  background(75);
  obstacle.display();
  for(var i = 0; i < balls.length; i++) {
    balls[i].display();
    balls[i].update();
    balls[i].edges();
   }
}

function mousePressed() {
   balls.push(new Ball(mouseX, mouseY));
 }

function Ball(x, y) {
  this.x = x;
  this.y = y;
  this.r = 15;
  this.gravity = 0.5;
  this.velocity = 0;
   this.display = function() {
     fill(255, 0 , 100);
     stroke(255);
     ellipse(this.x, this.y, this.r*2);
  }
    this.update = function() {
    this.velocity += this.gravity;
    this.y += this.velocity;
  }
  this.edges = function() {
    if (this.y >= windowHeight - this.r*2) {
       this.y = windowHeight - this.r*2;
      this.velocity = this.velocity* -1;
      this.gravity = this.gravity * 1.1;
    }
  }
}

function Obstacle() {
  this.x = windowWidth - windowWidth;
  this.y = windowHeight / 2;
  this.w = 200;
  this.h = 25;

  this.display = function() {
    fill(0);
    stroke(255);
    rect(this.x, this.y, this.w, this.h);
  }
}

function RectCircleColliding(Ball, Obstacle) {
     var distX = Math.abs(Ball.x - Obstacle.x - Obstacle.w / 2);
     var distY = Math.abs(Ball.y - Obstacle.y - Obstacle.h / 2);
    if (distX > (Obstacle.w / 2 + Ball.r)) {
        return false;
         console.log("no hit");
     }
    if (distY > (Obstacle.h / 2 + Ball.r)) {
         return false;
        console.log("no hit");
    }

    if (distX <= (Obstacle.w / 2)) {
         return true;
         console.log("hit");
    }
    if (distY <= (Obstacle.h / 2)) {
        return true;
        console.log("hit");
    }

    var dx = distX - Obstacle.w / 2;
    var dy = distY - Obstacle.h / 2;
     return (dx * dx + dy * dy <= (Ball.r * Ball.r));
}

I can't seem to get it to detect anything, I would appreciate any help. I'm using the p5.js library. I can't seem to get it to detect anything.

Scath
  • 3,777
  • 10
  • 29
  • 40
  • Have you tried debugging your code? Which line of code is behaving differently from what you expected? Can you please try to get something simpler working? What happens when you try just one hard-coded circle against one hard-coded rectangle? – Kevin Workman Apr 09 '18 at 23:40
  • The whole collision function just dosent seem to do anything at all. When running no errors are found but the balls just don’t interact with the object. – Peter_chura Apr 10 '18 at 03:59

1 Answers1

0

In the code you provided the function that checks the collision is never called and when it is, it doesn't work.

Here's my attempt at it. Changed the RectCircleColliding method and called it inside draw.

var balls = [];
var obstacle;

function setup() {
  createCanvas(windowWidth, windowHeight);
  obstacle = new Obstacle();
}

function draw() {
  background(75);
  obstacle.display();
  for(var i = 0; i < balls.length; i++) {
    balls[i].display();
    balls[i].update();
    balls[i].edges();
    console.log(RectCircleColliding(balls[i], obstacle));
   }
}

function mousePressed() {
   balls.push(new Ball(mouseX, mouseY));
 }

function Ball(x, y) {
  this.x = x;
  this.y = y;
  this.r = 15;
  this.gravity = 0.5;
  this.velocity = 0;
   this.display = function() {
     fill(255, 0 , 100);
     stroke(255);
     ellipse(this.x, this.y, this.r*2);
  }
    this.update = function() {
    this.velocity += this.gravity;
    this.y += this.velocity;
  }
  this.edges = function() {
    if (this.y >= windowHeight - this.r*2) {
       this.y = windowHeight - this.r*2;
      this.velocity = this.velocity* -1;
      this.gravity = this.gravity * 1.1;
    }
  }
}

function Obstacle() {
  this.x = windowWidth - windowWidth;
  this.y = windowHeight / 2;
  this.w = 200;
  this.h = 25;

  this.display = function() {
    fill(0);
    stroke(255);
    rect(this.x, this.y, this.w, this.h);
  }
}

function RectCircleColliding(Ball, Obstacle) {
    // define obstacle borders
    var bRight = Obstacle.x + Obstacle.w;
    var bLeft = Obstacle.x;
    var bTop = Obstacle.y;
    var bBottom = Obstacle.y + Obstacle.h;

    //compare ball's position (acounting for radius) with the obstacle's border
    if(Ball.x + Ball.r > bLeft)
        if(Ball.x - Ball.r < bRight)
            if(Ball.y + Ball.r > bTop)
                if(Ball.y - Ball.r < bBottom)
                    return(true);
    return false;
}
Julian
  • 1,277
  • 1
  • 9
  • 20
  • Serious caveat, though. This approach only works as long as the obstacle is not rotated. – Julian Apr 17 '18 at 03:03
  • Thanks, this seems to work very well. Do you know of a way I can make it work while rotating it, if my end goal was to create a rectangle slanted on each side of the canvas leading the balls to a slight opening. I know it's probably a more complicated process that will involve trigonometry. Any help is appreciated. – Peter_chura Apr 17 '18 at 12:21
  • You could take a look at [this](https://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection) to get a general idea of the algorithm and then take a look at the [p5.collide2d library](https://github.com/bmoren/p5.collide2D) – Julian Apr 18 '18 at 09:12