4

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!

3
  • I went to a hackathon the other week and worked with the canvas element for the first time. I found this to be an effective way of managing a canvas frame, nicely event driven. Also found this tutorial to be an incredible help. Commented Dec 30, 2013 at 20:27
  • @LawrenceJones, Thank you for both of them, they do like quite interesting. But I forgot to mention that I won't be using any frameworks or external libraries. It has to be done without the use of them Commented Dec 30, 2013 at 20:36
  • Dan, neither of those solutions make use of any external libraries. Whilst the first link may be surrounded by angular it's not reliant on it. Just pure javascript in the end. Commented Dec 30, 2013 at 20:39

1 Answer 1

8

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;
}
Sign up to request clarification or add additional context in comments.

7 Comments

I understand the logic behind this, and understand why it SHOULD work, but for some reason they still overlap? I also tried putting a console.log(); inside the if statement, but it doesn't show anything in the console
@Dan could be I misunderstood your question.. I interpreted it as you want to detect if two rectangles overlap (or intersects)? If you in addition need to prevent this (if they do) you can simply remove the rectangle that overlaps or not draw it.
I want to check if two of the rectangles overlap one another, so if they appear on top of each other, even if it's like 1px over the corner of another. And I know I should just remove it, but I don't know how to check if the rectangle is trying to spawn in a place that has already been taken
@Dan ah, before adding a new rectangle just iterate the array with existing rectangles and use the method on the new rectangle (the one not added yet). Updated answer.
Okay thank you, but there are two errors with this... 1) the for loop throws an error because there are not 3 parameters, 2) break at that point is an illegal statement
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.