user3045449
user3045449

Reputation:

Check if two items overlap on a canvas using JavaScript

I have a canvas, and I'm using geolocation, google maps and openweathermap to get the weather of where the user is. The weather will be taken and cause the game I'm making to also use that weather...

How can I check if two squares that are spawned onto the canvas overlap? This is the code for the rain, which looks nothing like rain at the moment...

function rectangle(x, y, w, h) {
    var randomx = Math.floor(Math.random() * canvas.width - 50);
    this.x = randomx || x || 0;
    this.y = y || 0;
    this.w = w || 0;
    this.h = h || 0;
    this.expired = false;

    this.draw = function() {
        cx.fillStyle = "blue";
        cx.fillRect(this.x, this.y, this.w, this.h);
    };

    this.update = function() {
        this.y++;
            if (y > canvas.height) {
                this.expired = true;
            }
    };
}

var rectangles = new Array();
function newRect() {
    rectangles.push(new rectangle(window.randomx, window.y, 10, 10));
}
var timing = 0;

function loop() {
    cx.clearRect(0, 0, canvas.width, canvas.height);
    if (timing % 10 === 0) {
        newRect();
    }

    for (var i = 0, l = rectangles.length; i < l; i++) {
        rectangles[i].update();
        rectangles[i].draw();
        if (rectangles[i].expired) {
            rectangles.splice(i, 1);
            i--;
        }
    }
    timing++;
    requestAnimFrame(loop);
}
loop();

My assumption, is that I need to perform a 'hit test' to see if two rectangles in the array are in the same perimeter... I guess where my this.draw and this.update function are I should do something like...

this.hitTest = function () {
    //Maths to check here
};

Then in the forloop do...

rectangles[i].hitTest();

But I'm not sure on the Maths or where to go from there...

Any help would be appreciated, thanks in advance!

Upvotes: 4

Views: 8819

Answers (1)

user1693593
user1693593

Reputation:

You can extend your rectangle object like this:

function rectangle(x, y, w, h) {

    ... existing code here ...

}

rectangle.prototype.intersects = function(rect) {
    return !( rect.x           > (this.x + this.w) || 
             (rect.x + rect.w) <  this.x           || 
              rect.y           > (this.y + this.h) ||
             (rect.y + rect.h) <  this.y);
}

Based on this code by Daniel Vassallo, adopted for your object.

Now simply call the function on the rectangle you want to compare with:

 if ( rectangles[x].intersects(rectangles[y]) ) {
     ... they intersect ...
 }

To check if a new rectangle intersects with an existing you can do:

function isOverlapping(myNewRect, rectangles) {

    for(var i = 0, r; r = rectangles[i]; i++) {
        if (myNewRect.intersect(r)) return true;
    }
    return false;
}

Upvotes: 8

Related Questions