Search code examples
javascriptcollision-detectioncollisiongeometryp5.js

p5.js rect circle collision, cant seem to get it to detect


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.


Solution

  • 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;
    }